İç içe nesneler nasıl sorgulanır?


205

İç içe nesneler gösterimi ile mongoDB sorgularken bir sorun var:

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

Ne yaptığımı göremiyorum. Nokta gösterim sorgusu ile aynı sonucu döndürmek için iç içe nesne gösterimi bekliyorum. Nerede yanılıyorum?

Yanıtlar:


420

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

Bu , başka bir alanın olmadığı headers eşit olan belgeleri sorgular { From: ... }.


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

Bu yalnızca headers.Fromalana bakar, içinde bulunan veya bulunmayan diğer alanlardan etkilenmez headers.


Nokta gösterim belgeleri


Bunu "headers.From" dan alıntı olmadan yapmanın bir yolu var mı?
trysis

Bilmiyorum, sadece merak ediyorum ve bazen faydalı olabileceğini düşündüm.
trysis

3
@trysis - Uygulamada, satır içi nesneleri bildirmenin (mongo [ose] belgelerindeki örnekler ve çoğu örnekte olduğu gibi) gerçek dünyada yeterli olmadığını gördüm. conditions['some.path'] = 'value'İş mantığımda olduğu gibi şeyler yapabileceğim 'koşullar' ve 'alanlar' nesneleri oluşturma alışkanlığını geliştirdim , sonra sonunda tek bir sorgu çalıştırın:find(conditions, fields, callback);
Ryan Wheale

Diyelim ki ne ben bu işi olmaz, "domain.com" içeren bir anahtara sahip: domains.domain.com. Bu senaryo için herhangi bir geçici çözüm var mı (domain.com'u başka bir şeye değiştirmeden örneğin domain_com)?
Rens Tillmann

1
Kendi yorumumu cevaplayarak, anahtarlarınızda noktaları tamamen kullanmaktan kaçınmak en iyisidir. Benim çözümümde, anahtarlar olan etki alanlarını tamamen terk ettim ve bunun yerine bir dilim / dizi oluşturdum.
Rens Tillmann

20

İki sorgu mekanizması, Alt Belgeler bölümündeki belgelerde önerildiği gibi farklı şekillerde çalışır :

Alan gömülü belgeyi (yani tuttuğunda alt belge ), ya tüm belirtebilirsiniz alt belge “içine ulaşılabilecek” bir alanın değerinin, ya da alt belgeyi tek tek alanlar için değerleri belirtmek için, nokta gösterimi kullanılarak alt belgeyi :

Alt belge, alan sırası da dahil olmak üzere, tam olarak belirtilen alt belgeyle eşleşiyorsa, belgeleri seçer.


Aşağıdaki örnekte sorgu, alan üreticisinin değerinin, yalnızca companydeğere sahip 'ABC123'alanı addressve değere sahip alanı '123 Street'tam sırayla içeren bir alt belge olduğu tüm belgeleri eşleştirir :

db.inventory.find( {
    producer: {
        company: 'ABC123',
        address: '123 Street'
    }
});

8
Deli oluyordum. Bu bana oldukça tutarsız görünüyor, çünkü nesneleri sorgularken doğrudan özellikleri herhangi bir sırayla eşleştirilebilir.
Capaj

7

MongoDB koleksiyonunun alt belgelerle sorgulanması konusunda çok fazla karışıklık olduğundan, yukarıdaki cevapları örneklerle açıklamanın değeceğini düşündüm:

İlk messageolarak koleksiyona sadece iki nesne ekledim: as:

> 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"
    }
}
>

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

Olması gereken bir belgeler için bu sorgular çünkü headersnesneye eşit {From: "reservations@marriott.com"}, sadece yani başka alanları içeren ya da biz bir alanın değeri olarak tüm alt belgeyi belirtmelidir.

@ Edmondo1984'ün cevabına göre

Alt belge, alan sırası da dahil olmak üzere tam olarak belirtilen alt belgeyle eşleşiyorsa, alt belgelerdeki eşitlik eşleşen belgeleri seçer .

Yukarıdaki ifadelerden aşağıdaki sorgu sonucu ne olmalıdır?

> db.messages.find({headers: {To: "kprasad.iitd@gmail.com", From: "reservations@marriott.com"}  }).count()
0

Ve ne sırasını değiştirmek eğer Fromve Toikinci dokümanların alt dokümanlarla aynı yani?

> db.messages.find({headers: {From: "reservations@marriott.com", To: "kprasad.iitd@gmail.com"}  }).count()
1

bu nedenle, alan sırası da dahil olmak üzere, belirtilen alt belgeyle tam olarak eşleşir .

Nokta operatörünü kullanmak için her biri için çok açık olduğunu düşünüyorum. Aşağıdaki sorgunun sonucunu görelim:

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

Yukarıdaki örnekle yapılan bu açıklamaların , alt belgelerle sorgu bulma konusunda daha fazla netlik kazanmasını umuyorum .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.