Bagaimana cara meminta objek bersarang?


204

Saya punya masalah ketika menanyakan mongoDB dengan notasi objek bersarang:

db.messages.find( { headers : { From: "reservations@marriott.com" } } ).count()
0
db.messages.find( { 'headers.From': "reservations@marriott.com" }  ).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

Jawaban:


420

db.messages.find( { headers : { From: "reservations@marriott.com" } } )

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


db.messages.find( { 'headers.From': "reservations@marriott.com" } )

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


Dokumentasi dot-notasi


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'
    }
});

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" : "reservations@marriott.com"
    }
}
{
    "_id" : ObjectId("5cce8eb97d2e7b3fe9c93c33"),
    "headers" : {
        "From" : "reservations@marriott.com",
        "To" : "kprasad.iitd@gmail.com"
    }
}
>

Jadi apa hasil dari kueri: db.messages.find({headers: {From: "reservations@marriott.com"} }).count()

Seharusnya satu karena pertanyaan ini untuk dokumen di mana headerssama dengan objek {From: "reservations@marriott.com"}, 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: "kprasad.iitd@gmail.com", From: "reservations@marriott.com"}  }).count()
0

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

> db.messages.find({headers: {From: "reservations@marriott.com", To: "kprasad.iitd@gmail.com"}  }).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': "reservations@marriott.com" }  ).count()
2

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.