Как запросить вложенные объекты?
У меня проблема при запросе mongoDB с вложенными объектами:
db.messages.find( { headers : { From: "[email protected]" } } ).count()
0
db.messages.find( { 'headers.From': "[email protected]" } ).count()
5
Я не вижу, что я делаю неправильно. Я ожидаю, что вложенное обозначение объекта вернет тот же результат, что и запрос точечной нотации. Где я ошибаюсь?
Ответы
Ответ 1
db.messages.find( { headers : { From: "[email protected]" } } )
Это запросы для документов, где headers
равно { From: ... }
, т.е. не содержит других полей.
db.messages.find( { 'headers.From': "[email protected]" } )
Это относится только к полю headers.From
, не затронутому другими полями, содержащимися или отсутствующими в headers
.
Документы с точными нотами
Ответ 2
Два механизма запроса работают по-разному, как предложено в документах в разделе Поддокументы:
Если поле содержит встроенный документ (т.е. поддокумент), вы можете указать весь поддокумент как значение поля или "достигнуть" вложенного документа с использованием точечной нотации, чтобы указать значения для отдельных полей в поддокументе
Соображения равенства в поддокументах выбирают документы, если поддокумент соответствует точно указанному вложенному документу, включая порядок полей.
В следующем примере запрос соответствует всем документам, в которых значение производителя поля является поддокументом, содержащим только поле company
со значением 'ABC123'
и поле address
со значением '123 Street'
, в точном порядке:
db.inventory.find( {
producer: {
company: 'ABC123',
address: '123 Street'
}
});
Ответ 3
Поскольку существует много путаницы в запросах mongodb collection с поддокументами, я подумал, что стоит объяснить приведенные выше ответы примерами:
Сначала я вставил только два объекта в коллекцию, а именно: message
как:
> db.messages.find().pretty()
{
"_id" : ObjectId("5cce8e417d2e7b3fe9c93c32"),
"headers" : {
"From" : "[email protected]"
}
}
{
"_id" : ObjectId("5cce8eb97d2e7b3fe9c93c33"),
"headers" : {
"From" : "[email protected]",
"To" : "[email protected]"
}
}
>
Итак, каков результат запроса: db.messages.find({headers: {From: "[email protected]"} }).count()
Это должен быть один запрос, так как он запрашивает документы, headers
равны объекту {From: "[email protected]"}
, т.е. Не содержат других полей, или мы должны указать весь поддокумент как значение поля.
Так в соответствии с ответом от @Edmondo1984
Равноправие в поддокументах выбирает документы, если поддокумент точно соответствует указанному поддокументу , включая порядок полей.
Из приведенных выше утверждений, каков должен быть результат запроса ниже?
> db.messages.find({headers: {To: "[email protected]", From: "[email protected]"} }).count()
0
А что если мы изменим порядок From
и To
то есть так же, как вложенные документы вторых документов?
> db.messages.find({headers: {From: "[email protected]", To: "[email protected]"} }).count()
1
таким образом, он точно соответствует указанному поддокументу, включая порядок полей.
Для использования точечного оператора, я думаю, это очень понятно для каждого. Давайте посмотрим на результат запроса ниже:
> db.messages.find( { 'headers.From': "[email protected]" } ).count()
2
Надеюсь, что это объяснение с примером сделает кого-то более ясным в поиске запроса с поддокументами.