1
resposta

PHP + mongoDriver

Eu estou tentando atualizar o valor de "posição" em "atributos" usando o operador $ set com arrayFilters. O comando abaixo funciona como esperado no terminal

db.produtos.insert(
  {
    "_id": 1,
    "nome":"Nome do Produto",
    "descricao":"Lorem ipsum dolor sit amet.",
    "atributos": [
      { "id" : 1, "posicao" : 2 },
      { "id" : 2, "posicao" : 1 },
      { "id" : 3, "posicao" : 3 }
    ]
  }
)

db.produtos.update(
  {"_id": 1 },
  {
    $set: {
      "atributos.$[elem1].posicao": 1,
      "atributos.$[elem2].posicao": 2,
      "atributos.$[elem3].posicao": 3
    }
  },
  {
     arrayFilters: [ 
       { "elem1.id": 1 },
       { "elem2.id": 2 },
       { "elem3.id": 3 },
     ]
   }
)

Mas quando tento criar o mesmo comando no PHP não funciona. Nos meus testes, o documento é encontrado, mas nunca atualizado. Só para explicar, recebo o "attributes.id" de uma string, montei um array com a atualização e outro para filtrar

<?php
$ids = explode(',', '1,2,3');

$update  = [];
$filters = [];

$i = 1;
foreach ($ids as $linha) :
   $update['atributos.$[elem'.$i.'].posicao'] = $i;

   $filters[]['elem'.$i.'.id'] = $linha;

   $i++;
endforeach;

$conexao = new MongoDB\Driver\Manager('mongodb://localhost:27017');

$cmd = new MongoDB\Driver\Command(
  [
    'findAndModify'  => 'produtos',
    'query'          => ['_id' => 1],
    'update'         => ['$set' => $update],
    'upsert'         => true,
    'returnDocument' => true,
    'new'            => true,
    'arrayFilters'   => $filters,
  ]
);

$result = $conexao->executeCommand('teste', $cmd)->toArray();
$result = json_decode(json_encode($result), true);

echo '<pre>';
print_r($cmd);
print_r($result);
1 resposta

Oi Lucas, tudo bom?

Pelo o que eu dei uma pesquisada aqui, utilizar a classe Command pode ser um pouco chato de configurar mesmo. O ideal no seu caso seria procurar alguma forma de realizar esses comandos passando apenas o texto (raw command), já que o comando no mongo funciona.

Porém, a galera do PHP liberou há alguns anos um Helper para realizar atualização de instancias no mongo com a classe MongoCollection. Na documentação tem exemplos de uso também. Talvez seja um bom norte.

Espero ter ajudado =)

Abraço