Trova il documento con una matrice che contiene un valore specifico

Se ho questo schema …

person = { name : String, favoriteFoods : Array } 

… dove l’array favoriteFoods è popolato da stringhe. Come posso trovare tutte le persone che hanno il “sushi” come cibo preferito con mangusta?

Speravo in qualcosa del tipo:

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

(So ​​che non c’è $contains in mongodb, solo spiegando cosa mi aspettavo di trovare prima di conoscere la soluzione)

Poiché favouriteFoods è una semplice serie di stringhe, puoi semplicemente eseguire una query direttamente sul campo:

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

Ma raccomanderei anche di rendere esplicito lo string array nel tuo schema:

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

Non c’è un operatore $contains in mongodb.

Puoi usare la risposta di JohnnyHK come funziona. L’analogia più vicina a contiene che mongo abbia $in , usando questa la tua query sarà simile a:

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

Mi sento come se $all fosse più appropriato in questa situazione. Se stai cercando una persona nel sushi, lo fai:

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

Come si potrebbe desiderare di filtrare più la tua ricerca, in questo modo:

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

$in è come OR e $all come AND. Controlla questo: https://docs.mongodb.com/manual/reference/operator/query/all/

Nel caso in cui sia necessario trovare documenti che contengono elementi NULL all’interno di una matrice di sotto-documenti, ho trovato questa query che funziona piuttosto bene:

 db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}}) 

Questa query è stata presa da questo post: array di query MongoDb con valori null

È stata una grande scoperta e funziona molto meglio della mia versione iniziale e sbagliata (che si è rivelata valida solo per gli array con un elemento):

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

Nel caso in cui la matrice contenga oggetti, ad esempio se favouriteFoods è una matrice di oggetti di quanto segue:

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

puoi usare la seguente query:

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

Per Loopback3 tutti gli esempi forniti non hanno funzionato per me, o comunque con l’utilizzo dell’API REST. Ma mi ha aiutato a capire la risposta esatta di cui avevo bisogno.

{"where":{"arrayAttribute":{ "all" :[String]}}}

Sebbene sia d’accordo con find () è più efficace nel tuo caso. C’è ancora una combinazione $ di strutture di aggregazione, per facilitare la ricerca di un gran numero di voci e generare un basso numero di risultati che hanno valore per te soprattutto per il raggruppamento e la creazione di nuovi file.

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

So che questo argomento è vecchio, ma per le persone future che potrebbero chiedersi la stessa domanda, un’altra soluzione incredibilmente inefficiente potrebbe essere quella di fare:

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

Questo evita tutte le ottimizzazioni di MongoDB, quindi non usare nel codice di produzione.