Me encontré con un problema que aún no he encontrado una solución. Tengo una colección con docenas de documentos en los que cada uno de los documentos contiene una lista (utilicemos el nombre 'lista' como clave para esa lista) con identificaciones de otros documentos (están conectados de alguna manera).
se eliminaron algunos de los documentos de la colección y trato de encontrar todos los documentos que contienen los identificadores de documentos que ya no existen en la colección.
ejemplo:
En cuanto al ejemplo anterior: quiero obtener el documento con la identificación: 5e3266e9bd724a000107a902 porque contiene una lista con la identificación 5e32a7f7bd724a00012c1104 que ya no existe.
Aquí hay una solución que funciona explotando $lookup en la misma colección (piense en "auto-JOIN"):
var r = [ {_id: 0, aa: [ 10, 11, 12 ] } ,{_id: 1, aa: [ 10, 11, 12 ] } ,{_id: 2, aa: [ 20, 21, 22 ] } // 21 is on watch list... ,{_id: 3, aa: [ 21, 20, 12 ] } // this one too and 21 is in different position ,{_id: 4, aa: [ 10, 22, 12 ] } ,{_id: 5, aa: [ 10, 22, 23 ] } // this one too... ,{_id: 6, aa: [ 10, 22, 21, 23 ] } // this one has BOTH 21 and 23 ,{_id: 10, X:10} ,{_id: 11, X:11} ,{_id: 12, X:12} ,{_id: 20, X:20} ,{_id: 21, X:21} ,{_id: 22, X:22} ,{_id: 23, X:23} ]; db.foo.insert(r); // Here is the whole thing: db.foo.aggregate([ ]); // Delete _id 21 and 23: db.foo.remove({_id: 21}); db.foo.remove({_id: 23}); // Double check: c = db.foo.aggregate([ ]); // Where does id 21 and/or 23 NOT exist anymore? Note we don't ask for 21 or 23. // We just know we expect a query to return docs that indicate 21 and/or 23 // are no longer there: c = db.foo.aggregate([ // NOTE! By using localField:'aa', we are asking for EACH element in the // array to be used as a value to match to _id (in the same collection): {$lookup: {from: 'foo', localField: 'aa', foreignField: '_id', as: 'X'}}, // Exploit "make a list of scalars from array of objects" notation by taking // input array $X and taking the _id field out: {$project: {X: {$setDifference: ["$aa", "$X._id"] }} }, // Keep those that match -- and protect against against empty sets // with $ifNull to turn a null into an array of len 0: {$match: {$expr: {$gt:[{$size: {$ifNull:['$X',[]]}}, 0]}} } ]); { "_id" : 2, "X" : [ 21 ] } { "_id" : 3, "X" : [ 21 ] } { "_id" : 5, "X" : [ 23 ] } { "_id" : 6, "X" : [ 21, 23 ] }