Digamos que tengo una base de datos Mongo que contiene objetos como:
[ { "test": { "123123": { "someField": null } } }, { "test": { "323143": { "someField": "lalala" }, "121434": { "someField": null } } }, { "test": { "4238023": { "someField": "afafa" } } }, ]Como puede ver, las teclas justo debajo de "prueba" pueden variar.
Quiero encontrar todos los documentos que tengan al menos un someField que no sea nulo.
Algo así como find : "test.*.someField": { $ne: null } (* representa cualquier valor aquí)
¿Cómo puedo hacer esto en mangosta? Estoy pensando que se necesitará una canalización de agregación aquí, pero no estoy exactamente seguro de cómo.
Restricciones:
La parte más complicada aquí es que no puede buscar claves que coincidan con un patrón. Afortunadamente hay una solución. Sí, necesita una canalización de agregación.
Veamos un documento individual:
{ "test": { "4238023": { "someField": "afafa" } } } Necesitamos consultar someField , pero para llegar a él, debemos eludir de alguna manera 4238023 porque varía con cada documento. ¿Qué pasaría si pudiéramos desglosar ese objeto de test y verlo presentado así:
{ "k": "4238023", "v": { "someField": "afafa" } } De repente, se vuelve mucho más fácil consultarlo. Bueno, la agregación de mongodb ofrece una función llamada $objectToArray que hace exactamente eso.
Entonces lo que vamos a hacer es:
test en una matriz para cada documento.v.someField no sea nulo.Entonces, aquí está la canalización que necesita:
db.collection.aggregate([ { "$project": { "arr": { "$objectToArray": "$$ROOT.test" } } }, { "$match": { arr: { $elemMatch: { "v.someField": { $ne: null } } } } }, { "$project": { "_id": 1, "test": { $arrayToObject: "$arr" } } } ])Zona de juegos: https://mongoplayground.net/p/b_VNuOLgUb2
Tenga en cuenta que en mongoose ejecutará esta agregación de la misma manera que lo haría en una terminal... bueno, además de .then .
YourCollection.aggregate([ ... ... ]) .then(result => console.log(result))