In MongoDB 2.0 e versioni precedenti, questo non è possibile. Quello che vuoi fare è restituire un elemento specifico dell'array, ma non è quello che sta facendo la tua proiezione, restituirà semplicemente l'intero array e quindi l'elemento z di ciascuno.
Tuttavia, con 2.2 (rc2 al momento della stesura di questa risposta), le cose sono leggermente migliorate. Ora puoi utilizzare $elemMatch come parte della tua proiezione (vedi SERVER-2238 per i dettagli) in modo da estrarre solo l'elemento dell'array richiesto. Quindi, prova qualcosa del genere:
db.foo.find({"ID":"123",'a':{$elemMatch:{'x':"/"}}},{_id : 0, 'a.$': 1})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
Oppure, usa semplicemente $elemMatch nella proiezione stessa, che potresti pensare sia più pulito:
db.foo.find({"ID":"123"},{_id : 0, 'a':{$elemMatch:{'x':"/"}}})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
Quindi, ora, almeno l'array restituito è solo quello contenente solo le voci desiderate e puoi semplicemente fare riferimento all'elemento z pertinente (le proiezioni elemMatch su un documento secondario non sono ancora supportate).
Ultimo ma non meno importante, in 2.2 abbiamo il framework di aggregazione, e una delle cose che può fare (con il $project
operatore, consiste nel rimodellare i documenti e modificare i documenti secondari e gli elementi dell'array in array di livello superiore. Per ottenere il risultato desiderato, faresti qualcosa del genere:
db.foo.aggregate(
{$match : {"ID":"123"}},
{$unwind : "$a"},
{$match : {"a.x":"/"}},
{$project : {_id : 0, z : "$a.z"}}
)
Il risultato è simile al seguente:
{ "result" : [ { "z" : "1000" } ], "ok" : 1 }