MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Come estrarre un'istanza di un elemento in un array in MongoDB?

Quindi hai ragione nel dire che il $pull l'operatore fa esattamente ciò che dice la documentazione in quanto i suoi argomenti sono in realtà una "query" utilizzata per abbinare gli elementi che devono essere rimossi.

Se il contenuto dell'array ha sempre l'elemento nella posizione "prima" mentre mostri, allora il $pop l'operatore rimuove infatti quel primo elemento.

Con il driver del nodo di base:

collection.findOneAndUpdate(
    { "array.0": "bird" },       // "array.0" is matching the value of the "first" element 
    { "$pop": { "array": -1 } },
    { "returnOriginal": false },
    function(err,doc) {

    }
);

Con mangusta l'argomento per restituire il documento modificato è diverso:

MyModel.findOneAndUpdate(
    { "array.0": "bird" },
    { "$pop": { "array": -1 } },
    { "new": true },
    function(err,doc) {

    }
);

Ma nessuno dei due è di grande utilità se la posizione dell'array del "primo" elemento da rimuovere non è nota.

Per l'approccio generale qui hai bisogno di "due" aggiornamenti, uno per abbinare il primo elemento e sostituirlo con qualcosa di unico da rimuovere, e il secondo per rimuovere effettivamente quell'elemento modificato.

Questo è molto più semplice se si applicano aggiornamenti semplici e non si richiede il documento restituito e può anche essere eseguito in blocco tra i documenti. Aiuta anche a usare qualcosa come async.series per evitare di annidare le tue chiamate:

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   
    }
);

Quindi usando il $unset qui con il $ posizionale operatore consente di modificare il "primo" elemento in null . Quindi la query successiva con $pull rimuove semplicemente qualsiasi null voce dall'array.

È così che rimuovi la "prima" occorrenza di un valore in modo sicuro da un array. Per determinare se quell'array contiene più di un valore che è lo stesso però è un'altra domanda.