Ответ 1
Используйте вложенный elemMatch
для поиска вложенных уровней внутри массивов.
Подробнее здесь.
Я спросил это как комментарий к другому вопросу, а также разместил вопрос о пользователе mongodb. Пока нет ответов, поэтому я прибегаю к задаче отдельного вопроса.
Если поле содержит массив, то оператор $in выбирает документы, чье поле содержит массив, содержащий хотя бы один элемент, который соответствует значению в указанном массиве (например,, и т.д.)
Я использую:
mongod --version:
db version v2.2.2, pdfile version 4.5
Thu May 30 12:19:12 git version: d1b43b61a5308c4ad0679d34b262c5af9d664267
mongo --version:
MongoDB shell version: 2.0.4
В оболочке MongoDB:
db.nested.insert({'level1': {'level2': [['item00', 'item01'], ['item10', 'item11']]}})
Здесь список запросов, которые должны работать в соответствии с документацией, и результаты, которые они производят:
Почему это не работает?
> db.nested.findOne({'level1.level2.0': 'item00'})
null
Зачем мне нужен $all?
> db.nested.findOne({'level1.level2.0': {'$all': ['item00']}})
{
"_id" : ObjectId("51a7a4c0909dfd8872f52ed7"),
"level1" : {
"level2" : [
[
"item00",
"item01"
],
[
"item10",
"item11"
]
]
}
}
Как минимум одно из следующего должно работать, правильно?
> db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})
null
> db.nested.findOne({'level1.level2': {'$in': ['item00']}})
null
Любые идеи? Мы рассматриваем отказ от MongoDB, если синтаксис запроса не работает, как рекламируется.
Спасибо!
Используйте вложенный elemMatch
для поиска вложенных уровней внутри массивов.
Подробнее здесь.
После выполнения некоторых запросов я пришел к выводу, что $in не работает для массива массивов.
Вместо этого вы можете использовать $elemMatch
, и это сработает, но разочарование в том, что документация MongoDB не предупреждает об этом.
Я создал этот документ:
{
"_id": "51cb12857124a215940cf2d4",
"level1": [
[
"item00",
"item01"
],
[
"item10",
"item11"
]
],
"items": [
"item20",
"item21"
]
}
Обратите внимание, что поле "items" - это массив строк, и этот запрос работает отлично:
db.nested.findOne({"items":{"$in":["item20"]} })
Теперь "level1.0" также представляет собой массив строк, единственное отличие заключается в том, что он находится внутри другого массива. Этот запрос должен работать, но это не так:
db.nested.findOne({"level1.0":{"$in":["item00"]} })
Единственный способ получить результат - использовать $elemMatch:
db.nested.findOne({"level1":{"$elemMatch":{"$in":['item00']}} })
Итак, $elemMatch
решает проблему, но реальное решение - обновить документацию MongoDB до состояния, что $in
не работает для массивов массивов. Возможно, вы должны отправить запрос на 10gen.
Короткий ответ: $in - для поля с одним значением, а $all - для массивов.
Во-первых, db.nested.findOne({'level1.level2.0': 'item00'})
не работает, потому что level1.level2.0 содержит массив, и вы пытаетесь сравнить его с одним значением.
Теперь db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})
не работает по той же причине. $in - для сравнения поля с одним значением (у вас есть массив) с несколькими значениями в массиве (указанном в запросе).
$ in говорит: дайте мне документы, у которых есть это поле, значение которого включено в этот массив.
$все работает, потому что говорит: дайте мне документы, у которых есть это поле с несколькими значениями, и все значения этого массива (в запросе) включены в это поле. (Под редакцией)
Невозможно получить, но посмотрите, что говорит документация для каждого:
$все выбирает документы, в которых поле содержит массив и содержит все элементы
(e.g. <value>, <value1>, etc.
) в массиве.$выбирает документы, в которых значение поля равно любому значению в указанном массиве (
e.g. <value1>, <value2>, etc.
)
Надеюсь, что это поможет