En el siguiente ejemplo, suponga que el documento está en la colección db.people .
¿Cómo eliminar el tercer elemento de la matriz de intereses por su índice ?
{
"_id" : ObjectId("4d1cb5de451600000000497a"),
"name" : "dannie",
"interests" : [
"guitar",
"programming",
"gadgets",
"reading"
]
}
Esta es mi solución actual:
var interests = db.people.findOne({"name":"dannie"}).interests;
interests.splice(2,1)
db.people.update({"name":"dannie"}, {"$set" : {"interests" : interests}});
¿Existe una forma más directa?
Respuestas:
No hay una forma directa de extraer / eliminar por índice de matriz. De hecho, este es un tema abierto http://jira.mongodb.org/browse/SERVER-1014 , puedes votarlo.
La solución alternativa es usar $ unset y luego $ pull:
Actualización: como se menciona en algunos de los comentarios, este enfoque no es atómico y puede causar algunas condiciones de carrera si otros clientes leen y / o escriben entre las dos operaciones. Si necesitamos que la operación sea atómica, podríamos:
fuente
Puede usar el
$pull
modificador deupdate
operación para eliminar un elemento particular en una matriz. En caso de que haya proporcionado una consulta, se verá así:Además, puede considerar usar
$pullAll
para eliminar todas las apariciones. Más sobre esto en la página de documentación oficial: http://www.mongodb.org/display/DOCS/Updating#Updating-%24pullEsto no usa el índice como criterio para eliminar un elemento, pero aún así podría ayudar en casos similares al suyo. En mi opinión, el uso de índices para direccionar elementos dentro de una matriz no es muy confiable ya que mongodb no es consistente en un orden de elementos tan rápido como yo lo sé.
fuente
En lugar de usar el no establecido (como en la respuesta aceptada), resuelvo esto configurando el campo en un valor único (es decir, no NULL) y luego inmediatamente extrayendo ese valor. Un poco más seguro desde una perspectiva asincrónica. Aquí está el código:
Con suerte, mongo abordará esto, tal vez extendiendo el modificador $ position para admitir $ pull y $ push.
fuente
Recomendaría usar un campo GUID (tiendo a usar ObjectID), o un campo de incremento automático para cada subdocumento en la matriz.
Con este GUID es fácil emitir un $ pull y asegurarse de que se extraiga el correcto. Lo mismo ocurre con otras operaciones de matriz.
fuente
A partir de
Mongo 4.4
, el$function
operador de agregación permite aplicar una función javascript personalizada para implementar el comportamiento no admitido por el lenguaje de consulta MongoDB.Por ejemplo, para actualizar una matriz eliminando un elemento en un índice determinado:
$function
toma 3 parámetros:body
, que es la función a aplicar, cuyo parámetro es la matriz a modificar. La función aquí simplemente consiste en usar empalme para eliminar 1 elemento en el índice 2.args
, que contiene los campos del registro que labody
función toma como parámetro. En nuestro caso"$interests"
.lang
, que es el idioma en el quebody
está escrita la función. Solojs
está disponible actualmente.fuente
en Mongodb 4.2 puedes hacer esto:
P es el índice del elemento que desea eliminar de la matriz.
Si desea eliminar de P hasta el final:
fuente
Para las personas que buscan una respuesta usando mangosta con nodejs. Así es como lo hago.
Puedo reescribir esta respuesta si no la entiendo muy bien, pero creo que está bien.
Espero que esto te ayude, he perdido mucho tiempo enfrentando este problema.
fuente
En lugar de usar $ pull, podemos usar $ pop para eliminar elementos en una matriz por su índice. Pero debe restar 1 de la posición del índice para eliminar según el índice.
Por ejemplo, si desea eliminar el elemento en el índice 0, debe usar -1, para el índice 1 debe usar 0 y así sucesivamente ...
Consulta para eliminar el tercer elemento (gadgets):
db.people.update({"name":"dannie"}, {'$pop': {"interests": 1}})
para referencia: https://docs.mongodb.com/manual/reference/operator/update/pop/
fuente
$pop
solo se puede eliminar el primer o último elemento de la matriz. La consulta en esta respuesta no elimina el tercer elemento.