Suchen Sie ein Dokument mit einem Array, das einen bestimmten Wert enthält

Wenn ich dieses Schema habe …

person = { name : String, favoriteFoods : Array } 

… wo das favoriteFoods Array mit Strings bestückt ist. Wie finde ich alle Personen, die “Sushi” als Lieblingsessen mit Mungo essen?

Ich habe auf etwas in der Art gehofft:

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

(Ich weiß, dass $contains in mongodb nicht $contains ist, ich erkläre nur, was ich erwartet habe, bevor ich die Lösung kenne)

   

Da favouriteFoods ein einfaches Array von Strings ist, können Sie dieses Feld direkt abfragen:

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

Aber ich würde auch empfehlen, das String-Array in Ihrem Schema explizit zu machen:

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

Es gibt keinen $contains Operator in mongodb.

Sie können die Antwort von JohnnyHK verwenden, wie das funktioniert. Die nächste Analogie zu enthält, dass Mongo hat ist $in , mit dieser Ihre Abfrage würde wie aussehen:

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

Ich fühle mich wie $all wäre in dieser Situation angemessener. Wenn Sie eine Person suchen, die Sushi macht, tun Sie Folgendes:

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

Wie Sie vielleicht mehr Ihre Suche filtern möchten, wie folgt:

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

$in ist wie OR und $all wie UND. Überprüfen Sie dies: https://docs.mongodb.com/manual/reference/operator/query/all/

Wenn Sie Dokumente finden müssen, die NULL-Elemente in einem Array von Unterdokumenten enthalten, habe ich diese Abfrage gefunden, die ziemlich gut funktioniert:

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

Diese Abfrage stammt aus diesem Post: MongoDb-Abfragearray mit Nullwerten

Es war ein großartiger Fund und es funktioniert viel besser als meine eigene anfängliche und falsche Version (was sich nur für Arrays mit einem Element als gut herausstellte):

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

Falls das Array Objekte enthält, zum Beispiel wenn favouriteFoods ein Array von Objekten der folgenden Art ist:

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

Sie können die folgende Abfrage verwenden:

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

Bei Loopback3 funktionierten alle angegebenen Beispiele für mich nicht oder so schnell wie die Verwendung der REST-API. Aber es half mir, die genaue Antwort herauszufinden, die ich brauchte.

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

Obwohl es mit find () übereinstimmt, ist es am effektivsten in Ihrem Anwendungsfall. Immer noch gibt es $ match of aggregation framework, um die Abfrage einer großen Anzahl von Einträgen zu erleichtern und eine geringe Anzahl von Ergebnissen zu generieren, die einen Wert für Sie haben, insbesondere für das Gruppieren und Erstellen neuer Dateien.

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

Ich weiß, dass dieses Thema alt ist, aber für zukünftige Menschen, die die gleiche Frage stellen könnten, könnte eine andere unglaublich ineffiziente Lösung sein:

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

Dies vermeidet alle Optimierungen durch MongoDB, also nicht im Produktionscode.