MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como puxar uma instância de um item em uma matriz no MongoDB?


Então você está correto em que o $pull O operador faz exatamente o que a documentação diz, pois seus argumentos são de fato uma "consulta" usada para corresponder aos elementos que devem ser removidos.

Se o conteúdo do seu array sempre tiver o elemento na posição "primeira" conforme você mostra, o $pop de fato, o operador remove esse primeiro elemento.

Com o driver de nó básico:
collection.findOneAndUpdate(
    { "array.0": "bird" },       // "array.0" is matching the value of the "first" element 
    { "$pop": { "array": -1 } },
    { "returnOriginal": false },
    function(err,doc) {

    }
);

Com mangusto o argumento para retornar o documento modificado é diferente:
MyModel.findOneAndUpdate(
    { "array.0": "bird" },
    { "$pop": { "array": -1 } },
    { "new": true },
    function(err,doc) {

    }
);

Mas também não são de muita utilidade se a posição da matriz do "primeiro" item a ser removido não for conhecida.

Para a abordagem geral aqui, você precisa de "duas" atualizações, sendo uma para corresponder ao primeiro item e substituí-lo por algo exclusivo a ser removido e o segundo para remover esse item modificado.

Isso é muito mais simples se aplicar atualizações simples e não solicitar o documento retornado, e também pode ser feito em massa entre documentos. Também ajuda usar algo como async.series para evitar aninhar suas chamadas:
async.series(
    [
        function(callback) {
            collection.update(
                { "array": "bird" },
                { "$unset": { "array.$": "" } },
                { "multi": true }
                callback
            );
        },
       function(callback) {
           collection.update(
                { "array": null },
                { "$pull": { "array": null } },
                { "multi": true }
                callback
           );
       }
    ],
    function(err) {
       // comes here when finished or on error   
    }
);

Então, usando o $unset aqui com o posicional $ operador permite que o "primeiro" item seja alterado para null . Em seguida, a consulta subsequente com $pull apenas remove qualquer null entrada da matriz.

É assim que você remove a "primeira" ocorrência de um valor com segurança de uma matriz. Para determinar se essa matriz contém mais de um valor que é o mesmo é outra questão.