Bagaimana cara meminta objek bersarang?

204

Saya punya masalah ketika menanyakan mongoDB dengan notasi objek bersarang:

db.messages.find( { headers : { From: "[email protected]" } } ).count()
0
db.messages.find( { 'headers.From': "[email protected]" }  ).count()
5

Saya tidak bisa melihat kesalahan saya. Saya mengharapkan notasi objek bersarang untuk mengembalikan hasil yang sama dengan permintaan notasi titik. Dimana saya salah

Edmondo1984
sumber

Jawaban:

420

db.messages.find( { headers : { From: "[email protected]" } } )

Ini permintaan untuk dokumen yang headers sama { From: ... } , yaitu tidak berisi bidang lain.


db.messages.find( { 'headers.From': "[email protected]" } )

Ini hanya melihat headers.Frombidang, tidak terpengaruh oleh bidang lain yang terkandung dalam, atau hilang dari headers,.


Dokumentasi dot-notasi

shx2
sumber
Apakah ada cara untuk melakukan ini tanpa tanda kutip di sekitar "header. Dari"?
trysis
Saya tidak tahu, hanya ingin tahu, dan berpikir itu kadang-kadang bermanfaat.
trysis
3
@trysis - Dalam praktiknya, saya telah menemukan bahwa mendeklarasikan objek inline (seperti contoh dalam mongo [ose] docs, dan dalam kebanyakan contoh di luar sana) tidak cukup di dunia nyata. Saya telah mengembangkan kebiasaan membuat objek 'kondisi' dan 'bidang' di mana saya dapat melakukan hal-hal seperti conditions['some.path'] = 'value'dalam logika bisnis saya, kemudian menjalankan satu permintaan di akhir:find(conditions, fields, callback);
Ryan Wheale
Bagaimana jika mari kita mengatakan bahwa saya memiliki kunci yang berisi "domain.com", ini tidak akan bekerja: domains.domain.com. Apakah ada solusi untuk skenario ini (tanpa mengubah domain.com menjadi sesuatu yang lain misalnya domain_com)?
Rens Tillmann
1
Menjawab komentar saya sendiri, yang terbaik adalah menghindari menggunakan titik sepenuhnya di kunci Anda. Dalam solusi saya, saya benar-benar membuang domain menjadi kunci, dan membuat irisan / array sebagai gantinya.
Rens Tillmann
20

Dua mekanisme kueri bekerja dengan cara yang berbeda, seperti yang disarankan dalam dokumen di bagian Sub-dokumen :

Ketika bidang memegang dokumen yang disematkan (yaitu, sub dokumen ), Anda dapat menentukan seluruh sub dokumen sebagai nilai bidang, atau “menjangkau” sub dokumen dengan menggunakan notasi titik, untuk menentukan nilai untuk bidang individual dalam sub dokumen :

Kesamaan kecocokan dalam subdokumen memilih dokumen jika sub dokumen cocok persis dengan sub dokumen yang ditentukan, termasuk urutan bidang.


Dalam contoh berikut, kueri cocok dengan semua dokumen di mana nilai produsen bidang adalah subdokumen yang hanya berisi bidang companydengan nilai 'ABC123'dan bidang addressdengan nilai '123 Street', dalam urutan yang tepat:

db.inventory.find( {
    producer: {
        company: 'ABC123',
        address: '123 Street'
    }
});
Edmondo1984
sumber
8
Saya menjadi gila. Menurut saya ini agak tidak konsisten, karena ketika menanyakan objek, properti langsungnya dapat dicocokkan dengan urutan apa pun.
Capaj
7

Karena ada banyak kebingungan tentang permintaan koleksi MongoDB dengan sub-dokumen , saya pikir layak untuk menjelaskan jawaban di atas dengan contoh:

Pertama, saya telah memasukkan hanya dua objek dalam koleksi yaitu: messagesebagai:

> db.messages.find().pretty()
{
    "_id" : ObjectId("5cce8e417d2e7b3fe9c93c32"),
    "headers" : {
        "From" : "[email protected]"
    }
}
{
    "_id" : ObjectId("5cce8eb97d2e7b3fe9c93c33"),
    "headers" : {
        "From" : "[email protected]",
        "To" : "[email protected]"
    }
}
>

Jadi apa hasil dari kueri: db.messages.find({headers: {From: "[email protected]"} }).count()

Seharusnya satu karena pertanyaan ini untuk dokumen di mana headerssama dengan objek {From: "[email protected]"}, hanya yaitu tidak mengandung bidang lain atau kita harus menentukan seluruh sub-dokumen sebagai nilai bidang.

Demikian sesuai jawaban dari @ Edmondo1984

Kesamaan kecocokan dalam sub-dokumen memilih dokumen jika sub dokumen cocok persis dengan sub-dokumen yang ditentukan, termasuk urutan bidang .

Dari pernyataan di atas, seperti apa hasil query di bawah ini?

> db.messages.find({headers: {To: "[email protected]", From: "[email protected]"}  }).count()
0

Dan bagaimana jika kita akan mengubah urutan Fromdan Toyaitu sama dengan sub-dokumen dari dokumen kedua?

> db.messages.find({headers: {From: "[email protected]", To: "[email protected]"}  }).count()
1

jadi, itu cocok persis dengan sub-dokumen yang ditentukan, termasuk urutan bidang .

Untuk menggunakan operator titik, saya pikir itu sangat jelas untuk setiap orang. Mari kita lihat hasil dari kueri di bawah ini:

> db.messages.find( { 'headers.From': "[email protected]" }  ).count()
2

Saya harap penjelasan ini dengan contoh di atas akan membuat seseorang lebih jernih menemukan permintaan dengan sub-dokumen .

krishna Prasad
sumber