Good day everyone. Suppose we have a collection and a document which looks something like this:
test_doc = {
\"ID\" : \"123\",
\"a\" : [
In MongoDB 2.0 and older, this is not possible. What you want to do is return a specific element of the array - but that is not what your projection is actually doing, it will just return the whole array and then the z element of each one.
However, with 2.2 (rc2 as of writing this answer), things have gotten a bit better. You can now use $elemMatch as part of your projection (see SERVER-2238 for details) so that you only pull back the required array element. So, try something like this:
db.foo.find({"ID":"123",'a':{$elemMatch:{'x':"/"}}},{_id : 0, 'a.$': 1})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
Or, just use $elemMatch in the projection itself, which you may think is cleaner:
db.foo.find({"ID":"123"},{_id : 0, 'a':{$elemMatch:{'x':"/"}}})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }
So, now, at least the array returned is only the one containing only the entries you want and you can simply reference the relevant z element (elemMatch projections on a subdocument are not yet supported).
Last but not least, in 2.2 we have the aggregation framework, and one of the things it can do (with the $project
operator, is to reshape your documents and change sub documents and array elements into top level arrays. To get your desired result, you would do something like this:
db.foo.aggregate(
{$match : {"ID":"123"}},
{$unwind : "$a"},
{$match : {"a.x":"/"}},
{$project : {_id : 0, z : "$a.z"}}
)
The result looks like this:
{ "result" : [ { "z" : "1000" } ], "ok" : 1 }