2015-01-13 19 views
11

varsayalım böyle bir koleksiyona sahip:Mongo Sorgu

{ "arr" : [ { "name" : "a", "num" : 1 }, { "name" : "a", "num" : 2 } ] }, 
{ "arr" : [ { "name" : "b", "num" : 1 }, { "name" : "a", "num" : 2 } ] }, 
{ "arr" : [ { "name" : "b", "num" : 1 }, { "name" : "b", "num" : 2 } ] } 

ve ben arr var tüm belgeler bulmak istediğiniz bir name = "b" ve num ile bir alt belgesi içeriyor = 2.

böyle bir sorgu yaparsanız: her bir su içerdiğinden

db.collection.find({ 
    $and: [ 
     { "arr.name": "b" }, 
     { "arr.num": 2 } 
    ] 
}); 

o koleksiyonunda tüm belgeleri döndürecektir b-belge ya "b" bir name ya ben de bu denedim 2.

bir num: Herhangi hataları atmak değil

db.collection.find({ 
    arr: [ 
     { "name": "b", "num": 2 } 
    ] 
}); 

, henüz herhangi bir sonuç vermez .

MongoDB'deki birden çok alt belge alanını nasıl sorgularsınız?

cevap

22

Bu $elemMatch operatör genellikle yanlış olsa bile bunun için var aslında. Aslında, dizinin içindeki "her" öğe üzerindeki sorgu koşullarını yerine getirir. Aksi açıkça denilen sürece tüm MongoDB argümanlar bir "ve" operasyon şunlardır: Yalnızca uyumlu alan ve bu değil bekliyoruz

db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2 } } }) 

Muhtemelen aynı zamanda burada "proje" istediğiniz bütün belge:

ikinci girişim, bu sorguyu neden çalışmıyor Nihayet

db.collection.find(
    { "arr": { "$elemMatch": { "name": "b", "num": 2 } } }, 
    { "arr.$": 1 } 
) 
açıklamaya:

db.collection.find({ 
    "arr": [ 
     { "name": "b", "num": 2 } 
    ] 
}) 

hiçbir gerçek do olmadığından herhangi bir şey eşleşmiyor "arr" ifadesinin, koşullarınıza tam olarak uyan tekil bir öğe içerdiği yer.

İlk örnek başarısız ..: koşulları karşılayan ve bu sadece her iki durumun aynı eleman için geçerli olduğunu kabul edilmez birkaç dizi elemanları vardır

db.collection.find({ 
    $and: [ 
     { "arr.name": "b" }, 
     { "arr.num": 2 } 
    ] 
}); 

çünkü. Bu, $elemMatch'un eklediği şeydir ve eşleşecek bir koşula daha fazla ihtiyaç duyduğunuzda, bu, onu kullandığınız yerdir.

+1

Çok faydalı ve eksiksiz bir cevap, iki kez yükseltemediğim için üzgünüm. Teşekkürler Neil! – Moppo