Rechercher un document avec un tableau contenant une valeur spécifique

Si j’ai ce schéma …

person = { name : Ssortingng, favoriteFoods : Array } 

… où le tableau favoriteFoods est rempli avec des chaînes. Comment puis-je trouver toutes les personnes qui ont un “sushi” comme nourriture préférée en utilisant de la mongoose?

J’espérais quelque chose comme:

 PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...}); 

(Je sais qu’il n’y a pas de $contains dans mongodb, juste pour expliquer ce que je m’attendais à trouver avant de connaître la solution)

Comme favouriteFoods est un tableau simple de chaînes, vous pouvez simplement interroger directement ce champ:

 PersonModel.find({ favouriteFoods: "sushi" }, ...); 

Mais je vous recommande également de rendre le tableau de chaînes explicite dans votre schéma:

 person = { name : Ssortingng, favouriteFoods : [Ssortingng] } 

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 a est $in , en utilisant ceci, votre requête ressemblerait à ceci:

 PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...); 

Je pense que $all serait plus approprié dans cette situation. Si vous cherchez une personne qui aime les sushis, vous faites:

 PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...}) 

Comme vous pourriez vouloir filtrer plus votre recherche, comme ceci:

 PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...}) 

$in est comme OR et $all like AND. Vérifiez ceci: https://docs.mongodb.com/manual/reference/operator/query/all/

Si vous avez 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 est extraite de cet article: Tableau de requête MongoDb avec des valeurs NULL

C’était une bonne trouvaille et cela fonctionne beaucoup mieux que ma propre version initiale et fausse (qui s’est avérée bien fonctionner uniquement pour les tableaux avec un élément):

 .find({ 'MyArrayOfSubDocuments': { $not: { $size: 0 } }, 'MyArrayOfSubDocuments._id': { $exists: false } }) 

Dans le cas où le tableau contient des objects, par exemple si favouriteFoods est un tableau d’objects parmi les suivants:

 { name: 'Sushi', type: 'Japanese' } 

vous pouvez utiliser la requête suivante:

 PersonModel.find({"favouriteFoods.name": "Sushi"}); 

Pour Loopback3, tous les exemples donnés ne fonctionnaient pas pour moi ou aussi rapidement que l’utilisation de l’API REST. Mais cela m’a aidé à trouver la réponse exacte dont j’avais besoin.

{"where":{"arrayAtsortingbute":{ "all" :[Ssortingng]}}}

Bien que d’accord avec find (), c’est le plus efficace dans votre cas. Il y a toujours la structure $ match of aggregation, pour faciliter la recherche d’un grand nombre d’entrées et générer un faible nombre de résultats qui ont de la valeur pour vous, notamment pour regrouper et créer de nouveaux fichiers.

  PersonModel.aggregate([ { "$match": { $and : [{ 'favouriteFoods' : { $exists: true, $in: [ 'sushi']}}, ........ ] } }, { $project : {"_id": 0, "name" : 1} } ]); 

Je sais que ce sujet est ancien, mais pour les personnes futures qui pourraient se demander la même question, une autre solution incroyablement inefficace pourrait être de faire:

 PersonModel.find({$where : 'this.favouriteFoods.indexOf("sushi") != -1'}); 

Cela évite toutes les optimisations par MongoDB, donc ne pas utiliser dans le code de production.