Если у меня есть эта схема...
person = {
name : String,
favoriteFoods : Array
}
... где массив favoriteFoods
заполняется строками. Как я могу найти всех людей, которые имеют "суши" как свою любимую пищу с помощью мангуста?
Я надеялся на что-то вроде:
PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});
(Я знаю, что в mongodb нет $contains
, просто объясняя, что я ожидал найти, прежде чем знать решение)
Поскольку favouriteFoods
- это простой массив строк, вы можете просто запросить это поле напрямую:
PersonModel.find({ favouriteFoods: "sushi" }, ...);
Но я также рекомендую сделать строковый массив явным в вашей схеме:
person = {
name : String,
favouriteFoods : [String]
}
В mongodb нет оператора $contains
.
Вы можете использовать ответ JohnnyHK, который работает. Ближайшая аналогия с тем, что mongo имеет $in
, используя этот запрос, будет выглядеть так:
PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);
Если вам нужно найти документы, содержащие элементы NULL внутри массива поддокументов, я нашел этот запрос, который работает очень хорошо:
db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})
Этот запрос взят из этого сообщения: массив запросов MongoDb с нулевыми значениями
Это была отличная находка, и она работает намного лучше, чем моя первоначальная и неправильная версия (которая, как оказалось, отлично работает только для массивов с одним элементом):
.find({
'MyArrayOfSubDocuments': { $not: { $size: 0 } },
'MyArrayOfSubDocuments._id': { $exists: false }
})
Мне кажется, что $all
будет более уместным в этой ситуации. Если вы ищете человека, который находится в суши, вы делаете:
PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})
Как вы можете захотеть отфильтровать больше вашего поиска, например:
PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})
$in
подобен OR и $all
как AND. Проверьте это: https://docs.mongodb.com/manual/reference/operator/query/all/
Если массив содержит объекты, например, если favouriteFoods
- это массив объектов следующего типа:
{
name: 'Sushi',
type: 'Japanese'
}
вы можете использовать следующий запрос:
PersonModel.find({"favouriteFoods.name": "Sushi"});
Я знаю, что эта тема старая, но для будущих людей, которые могут задаться вопросом по тому же вопросу, можно было бы сделать еще одно невероятно неэффективное решение:
PersonModel.find({$where : 'this.favouriteFoods.indexOf("sushi") != -1'});
Это позволяет избежать всех оптимизаций MongoDB, поэтому не используйте в производственном коде.
favouriteFoods
является:favouriteFoods:[{type:Schema.Types.ObjectId, ref:'Food'}]