I MongoDB 2.0 och äldre är detta inte möjligt. Vad du vill göra är att returnera ett specifikt element i arrayen - men det är inte vad din projektion faktiskt gör, den kommer bara att returnera hela arrayen och sedan z-elementet för var och en.
Men med 2.2 (rc2 när det här svaret skrevs) har det blivit lite bättre. Du kan nu använda $elemMatch som en del av din projektion (se SERVER-2238 för detaljer) så att du bara drar tillbaka det nödvändiga arrayelementet. Så prova något sånt här:
db.foo.find({"ID":"123",'a':{$elemMatch:{'x':"/"}}},{_id : 0, 'a.$': 1})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
Eller använd bara $elemMatch i själva projektionen, som du kanske tycker är renare:
db.foo.find({"ID":"123"},{_id : 0, 'a':{$elemMatch:{'x':"/"}}})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
Så nu är åtminstone den array som returneras bara den som bara innehåller de poster du vill ha och du kan helt enkelt referera till det relevanta z-elementet (elemMatch-projektioner på ett underdokument stöds inte ännu).
Sist men inte minst, i 2.2 har vi aggregeringsramverket, och en av de saker som det kan göra (med $project
operator, är att omforma dina dokument och ändra underdokument och matriselement till toppnivåmatriser. För att få önskat resultat skulle du göra något så här:
db.foo.aggregate(
{$match : {"ID":"123"}},
{$unwind : "$a"},
{$match : {"a.x":"/"}},
{$project : {_id : 0, z : "$a.z"}}
)
Resultatet ser ut så här:
{ "result" : [ { "z" : "1000" } ], "ok" : 1 }