Si j'ai ce schéma ...
person = {
name : String,
favoriteFoods : Array
}
... où le tableau favoriteFoods
est rempli de chaînes. Comment trouver toutes les personnes qui ont le "sushi" comme aliment préféré à base de mangouste?
J'espérais quelque chose du genre:
PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});
(Je sais qu'il n'y a pas de $contains
dans mongodb, expliquant simplement ce que je m'attendais à trouver avant de connaître la solution)
Comme favouriteFoods
est un simple tableau de chaînes, vous pouvez simplement interroger ce champ directement:
PersonModel.find({ favouriteFoods: "sushi" }, ...);
Mais je vous recommanderais également de rendre le tableau de chaînes explicite dans votre schéma:
person = {
name : String,
favouriteFoods : [String]
}
Il n'y a pas d'opérateur $contains
dans mongodb.
Vous pouvez utiliser la réponse de JohnnyHK comme cela fonctionne. L'analogie la plus proche de contient que mongo est $in
, avec ceci votre requête ressemblerait à ceci:
PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);
Je pense que $all
serait plus approprié dans cette situation. Si vous recherchez une personne qui aime le sushi, vous le faites:
PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})
Comme vous voudrez peut-être filtrer davantage votre recherche, comme ceci:
PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})
$in
est comme OR et $all
comme AND. Vérifiez ceci: https://docs.mongodb.com/manual/reference/operator/query/all/
Si le tableau contient des objets, par exemple, si favouriteFoods
est un tableau d'objets du type suivant:
{
name: 'Sushi',
type: 'Japanese'
}
vous pouvez utiliser la requête suivante:
PersonModel.find({"favouriteFoods.name": "Sushi"});
Au cas où vous auriez besoin de trouver des documents contenant des éléments NULL dans un tableau de sous-documents, j'ai trouvé cette requête qui fonctionne plutôt bien:
db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})
Cette requête provient de cet article: Tableau de requêtes MongoDb avec des valeurs NULL
C'était une excellente découverte et cela fonctionne beaucoup mieux que ma propre version initiale et fausse (qui s'est avérée ne fonctionner correctement que pour les tableaux contenant un seul élément):
.find({
'MyArrayOfSubDocuments': { $not: { $size: 0 } },
'MyArrayOfSubDocuments._id': { $exists: false }
})
Bien qu'accepter, find () est le plus efficace dans votre cas d'utilisation. Néanmoins, il existe toujours une correspondance de structure d'agrégation pour faciliter l'interrogation d'un grand nombre d'entrées et générer un faible nombre de résultats qui ont une valeur pour vous, en particulier pour le regroupement et la création de nouveaux fichiers.
PersonModel.aggregate([ { "$match": { $and : [{ 'favouriteFoods' : { $exists: true, $in: [ 'sushi']}}, ........ ] } }, { $project : {"_id": 0, "name" : 1} } ]);
Pour Loopback3, tous les exemples donnés ne fonctionnaient pas pour moi ou aussi rapidement que l’utilisation de l’API REST de toute façon. Mais cela m'a aidé à trouver la réponse exacte dont j'avais besoin.
{"where":{"arrayAttribute":{ "all" :[String]}}}
Si vous souhaitez utiliser quelque chose comme un opérateur "contient" via javascript, vous pouvez toujours utiliser une expression régulière pour cela ...
par exemple . Disons que vous voulez récupérer un client ayant pour nom "Bartolomew"
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);
}
Le cas où lookup_food_array est un tableau.
match_stage["favoriteFoods"] = {'$elemMatch': {'$in': lookup_food_array}}
Si cas de lookup_food_array est une chaîne.
match_stage["favoriteFoods"] = {'$elemMatch': lookup_food_string}