mongodb - español - mongoose schema
Encontrar documento con matriz que contiene un valor específico (9)
Si tengo este esquema ...
person = {
name : String,
favoriteFoods : Array
}
... donde la matriz favoriteFoods
se rellena con cadenas. ¿Cómo puedo encontrar a todas las personas que tienen "sushi" como su comida favorita usando la mangosta?
Esperaba algo como:
PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});
(Sé que no hay $contains
en mongodb, solo explicando lo que esperaba encontrar antes de saber la solución)
Aunque de acuerdo con find () es más efectivo en su caso de uso. Todavía hay $ coincidencia del marco de agregación, para facilitar la consulta de un gran número de entradas y generar un bajo número de resultados que tienen valor especialmente para agrupar y crear nuevos archivos.
PersonModel.aggregate([ { "$match": { $and : [{ ''favouriteFoods'' : { $exists: true, $in: [ ''sushi'']}}, ........ ] } }, { $project : {"_id": 0, "name" : 1} } ]);
Como favouriteFoods
es una simple serie de cadenas, puedes consultar ese campo directamente:
PersonModel.find({ favouriteFoods: "sushi" }, ...);
Pero también recomendaría que la matriz de cadenas sea explícita en su esquema:
person = {
name : String,
favouriteFoods : [String]
}
En caso de que la matriz contenga objetos, por ejemplo, si favouriteFoods
es una matriz de objetos de los siguientes:
{
name: ''Sushi'',
type: ''Japanese''
}
Puedes usar la siguiente consulta:
PersonModel.find({"favouriteFoods.name": "Sushi"});
En caso de que necesite encontrar documentos que contengan elementos NULL dentro de una matriz de sub-documentos, he encontrado esta consulta que funciona bastante bien:
db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})
Esta consulta se toma de esta publicación: matriz de consultas MongoDb con valores nulos
Fue un gran hallazgo y funciona mucho mejor que mi propia versión inicial e incorrecta (que resultó funcionar bien solo para arreglos con un elemento):
.find({
''MyArrayOfSubDocuments'': { $not: { $size: 0 } },
''MyArrayOfSubDocuments._id'': { $exists: false }
})
No hay $contains
operador en mongodb.
Puedes usar la respuesta de JohnnyHK como funciona. La analogía más cercana a los contenidos que tiene mongo es $in
, usando esto, su consulta se vería así:
PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);
Para Loopback3, todos los ejemplos dados no funcionaron para mí, o tan rápido como usar la API REST de todos modos. Pero me ayudó a descubrir la respuesta exacta que necesitaba.
{"where":{"arrayAttribute":{ "all" :[String]}}}
Sé que este tema es antiguo, pero para las personas futuras que podrían plantearse la misma pregunta, otra solución increíblemente ineficiente podría ser:
PersonModel.find({$where : ''this.favouriteFoods.indexOf("sushi") != -1''});
Esto evita todas las optimizaciones de MongoDB, por lo que no se utiliza en el código de producción.
Si desea usar algo como un operador "contiene" a través de javascript, siempre puede usar una expresión regular para eso ...
p.ej. Digamos que desea recuperar un cliente que tenga "Bartolomew" como nombre
async function getBartolomew() {
const custStartWith_Bart = await Customers.find({name: /^Bart/ }); // Starts with Bart
const custEndWith_lomew = await Customers.find({name: /lomew$/ }); // Ends with lomew
const custContains_rtol = await Customers.find({name: /.*rtol.*/ }); // Contains rtol
console.log(custStartWith_Bart);
console.log(custEndWith_lomew);
console.log(custContains_rtol);
}
Siento que $all
sería más apropiado en esta situación. Si estás buscando una persona que esté en el sushi, haces:
PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})
Como es posible que desee filtrar más su búsqueda, así:
PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})
$in
es como OR y $all
como AND. Compruebe esto: https://docs.mongodb.com/manual/reference/operator/query/all/