sql >> Base de Datos >  >> NoSQL >> MongoDB

¿Cómo extraer una instancia de un elemento en una matriz en MongoDB?

Entonces tiene razón en que $pull El operador hace exactamente lo que dice la documentación en el sentido de que sus argumentos son, de hecho, una "consulta" utilizada para hacer coincidir los elementos que se eliminarán.

Si el contenido de su matriz siempre tiene el elemento en la "primera" posición como muestra, entonces el $pop de hecho, el operador elimina ese primer elemento.

Con el controlador de nodo 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) {

    }
);

Con mangosta, el argumento para devolver el documento modificado es diferente:

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

    }
);

Pero tampoco son de mucha utilidad si no se conoce la posición de la matriz del "primer" elemento que se eliminará.

Para el enfoque general aquí, necesita "dos" actualizaciones, una para que coincida con el primer elemento y lo reemplace con algo único para eliminar, y la segunda para eliminar realmente ese elemento modificado.

Esto es mucho más simple si se aplican actualizaciones simples y no se solicita el documento devuelto, y también se puede hacer de forma masiva en todos los documentos. También ayuda usar algo como async.series para evitar anidar sus llamadas:

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

Entonces usando el $unset aquí con el $ posicional el operador permite que el "primer" elemento se cambie a null . Luego la consulta posterior con $pull simplemente elimina cualquier null entrada de la matriz.

Así es como elimina la "primera" ocurrencia de un valor de forma segura de una matriz. Sin embargo, determinar si esa matriz contiene más de un valor que es el mismo es otra cuestión.