В MongoDB 2.0 и по-стари версии това не е възможно. Това, което искате да направите, е да върнете конкретен елемент от масива - но това не е, което всъщност прави вашата проекция, тя просто ще върне целия масив и след това z елемента на всеки един.
Въпреки това, с 2.2 (rc2 към момента на писане на този отговор), нещата са станали малко по-добри. Вече можете да използвате $elemMatch като част от вашата проекция (вижте SERVER-2238 за подробности), така че да изтеглите само необходимия елемент от масива. Така че опитайте нещо подобно:
db.foo.find({"ID":"123",'a':{$elemMatch:{'x':"/"}}},{_id : 0, 'a.$': 1})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
Или просто използвайте $elemMatch в самата проекция, което може да мислите, че е по-чисто:
db.foo.find({"ID":"123"},{_id : 0, 'a':{$elemMatch:{'x':"/"}}})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
Така че сега поне върнатият масив е само този, съдържащ само желаните от вас записи и можете просто да препратите към съответния z елемент (elemMatch проекциите на поддокумент все още не се поддържат).
Не на последно място, във 2.2 имаме рамката за агрегиране и едно от нещата, които може да прави (с $project
оператор, е да преформатира вашите документи и да промени поддокументите и елементите на масива в масиви от най-високо ниво. За да получите желания резултат, трябва да направите нещо подобно:
db.foo.aggregate(
{$match : {"ID":"123"}},
{$unwind : "$a"},
{$match : {"a.x":"/"}},
{$project : {_id : 0, z : "$a.z"}}
)
Резултатът изглежда така:
{ "result" : [ { "z" : "1000" } ], "ok" : 1 }