NodeJS / Mongoose / MongoDB – Pull (from array) no funciona

Estoy tratando de extraer / eliminar valores de una matriz (subdocumento).

Ejemplo doc:

{ _id: 5150a1199fac0e6910000002, name: 'some name, items: [{ id: 23, name: 'item name 23' },{ id: 24, name: 'item name 24' }] } 

Tengo el documento en la memoria cuando ya lo saqué de Mongo. Estoy intentando:

 var left = object.items.pull({id: 24}); console.log(left) 

Salidas:

 [{ id: 23, name: 'item name 23', _id: 5150a1199fac0e6910000045 },{ id: 24, name: 'item name 24', _id: 5150a1199fac0e6910000002 }] 

Así que parece que ya tengo un problema. La matriz devuelta a partir de la llamada de extracción debería estar en la matriz después de la extracción. No estoy seguro de por qué no se extrajo de la matriz de elementos. ¿Esto solo admite la extracción por parte de ObjectId y campos no definidos por el usuario?

Llamo guardar

 object.save(); 

Mongoose registra esto como la consulta:

 Mongoose: mycollection.update({ _id: ObjectId("5150901ac345824a07000002"), __v: 3 }) { '$inc': { __v: 1 }, '$pull': { attachments: { _id: { '$in': [ ObjectId("5150c64d63773efb1f000002") ] } } } } {} 

Esto muestra por qué mi documento no se está eliminando. El _id del elemento de matriz que debe eliminarse es:

 _id: 5150a1199fac0e6910000002 

El elemento que mongoose está enviando a la base de datos para eliminar es:

 ObjectId("5150c64d63773efb1f000002") 

¿Alguna idea de lo que estoy haciendo mal? Estoy tratando de eliminar por algo que no sea _id, no estoy seguro de si eso es posible, pero desde los documentos parece ser.

Descubrí que el comando $ pull tampoco funciona para mí a menos que incluya la callback en la lista de argumentos.

En mi situación, este formato no funcionó:

 UserAlerts.findOneAndUpdate({userId: userId}, {$pull: {alerts: {_id: alertId}}}); 

Pero este formato hizo:

 UserAlerts.findOneAndUpdate({userId: userId}, {$pull: {alerts: {_id: alertId}}}, function(err, data){ console.log(err, data); }); 

Según la documentación, parece que ambos deberían funcionar, pero no lo hacen. La razón es porque la primera forma requiere que llame a .exec () en el objeto devuelto, mientras que la versión de callback llama a exec () automáticamente. Causó un poco de confusión para mí también.

Así que necesitas hacer algo como esto:

 UserAlerts.findOneAndUpdate({userId: userId}, {$pull: {alerts: {_id: alertId}}}).exec();