Tengo un problema que se considera tan simple. Dados documentos anidados que tienen un campo de caducidad. Un documento de ejemplo:

{
   _id: ObjectId(),
   stuff: [
     {
        name: 'egg',
        expires: ISODate("2019-07-19T12:52:56.163Z")
     },
     {
        name: 'potato',
        expires: ISODate("2019-07-19T12:52:56.163Z")
     }
   ]
}

Pensé que podría usar una consulta como esa:

db.collection.update({"_id": ObjectId("578411d30af77c226c52b940")}, { 
  "$pull": { 
    "stuff.expires": { "$lt": ISODate() } 
  } 
});

Posiblemente pueda aplicar eso a varios documentos a la vez, pero incluso cuando intento actualizar un solo documento, me encuentro con ese error:

No se puede usar la parte (expira) de (stuff.expires) para atravesar el elemento

Probé un montón de modificaciones, pero no pude encontrar una manera de hacer que esto funcione o un ejemplo similar (que parece ser bastante extraño cuando busco cosas de mongodb).

Si no hay forma de actualizar varios documentos a la vez, estaría feliz si hubiera una forma de eliminar todos los elementos caducados de un solo documento en una consulta atómica. No es necesario que la consulta funcione con versiones anteriores de mongodb; la última versión está bien.

1
st-h 22 oct. 2019 a las 20:35

1 respuesta

La mejor respuesta

Creo que puedes lograr lo que quieres usando esta consulta:

db.collection.update({}, {
    $pull: {
        stuff: {
            expires: {
                $lt: ISODate()
            }
        }
    }
}, {
    multi: true
})

La consulta anterior apuntará a todos los documentos y extraerá cada objeto stuff cuya propiedad caduque sea más baja que su ISODate() el multi:true es la opción que permite actualizar varios documentos

2
Matheus Hatje 22 oct. 2019 a las 17:53