In mongoDB (2.4) I have collection students
with bunch of documents in it. Each document will have structure as below:
{
"_id" : ObjectId("55f16640a17eed480bb0dc18"),
"messages" : [
{
"_id" : ObjectId("55fc60bc260c9be5879ef733"),
"createdOn" : ISODate("2015-09-18T19:06:36.793Z"),
"fromUser" : ObjectId("55f16a6af9c703280c5b2c0e"),
"toUser" : ObjectId("55f16640a17eed480bb0dc18"),
"type" : 1
},
{
"_id" : ObjectId("55fc6d200d6097e98b210bff"),
"createdOn" : ISODate("2015-09-18T19:59:28.439Z"),
"fromUser" : ObjectId("55f721d1e1242e7c4c129471"),
"toUser" : ObjectId("55f16640a17eed480bb0dc18"),
"type" : 1
}
]
}
Now, I need to pull out one of the subdocuments from messages array, say with messages._id
equal 55fc60bc260c9be5879ef733
so I use $elemMatch
:
db.users.find({"_id": new ObjectId('55f16640a17eed480bb0dc18'),
"messages": {
$elemMatch:{
"_id": new ObjectId('55fc60bc260c9be5879ef733'),
"fromUser": new ObjectId('55f16a6af9c703280c5b2c0e'),
"toUser": new ObjectId('55f16640a17eed480bb0dc18'),
"type": 1
}}}).pretty();
But this gives me:
{
"_id" : ObjectId("55f16640a17eed480bb0dc18"),
"messages" : [
{
"_id" : ObjectId("55fc60bc260c9be5879ef733"),
"createdOn" : ISODate("2015-09-18T19:06:36.793Z"),
"fromUser" : ObjectId("55f16a6af9c703280c5b2c0e"),
"toUser" : ObjectId("55f16640a17eed480bb0dc18"),
"type" : 1
},
{
"_id" : ObjectId("55fc6d200d6097e98b210bff"),
"createdOn" : ISODate("2015-09-18T19:59:28.439Z"),
"fromUser" : ObjectId("55f721d1e1242e7c4c129471"),
"toUser" : ObjectId("55f16640a17eed480bb0dc18"),
"type" : 1
}
]
}
If I understand docs correctly http://docs.mongodb.org/v2.4/reference/operator/projection/elemMatch/ I should receive only:
{
"_id" : ObjectId("55f16640a17eed480bb0dc18"),
"messages" : [
{
"_id" : ObjectId("55fc60bc260c9be5879ef733"),
"createdOn" : ISODate("2015-09-18T19:06:36.793Z"),
"fromUser" : ObjectId("55f16a6af9c703280c5b2c0e"),
"toUser" : ObjectId("55f16640a17eed480bb0dc18"),
"type" : 1
}
]
}
So what am I doing wrong?
You are not using the projection operator $elemMatch
match, but the query operator $elemMatch
In other words, you don't project anything, but use $elemMatch
for filtering the results that your query should return.
In order for your projection to work, you should change your query to something like:
db.users.find(
{"_id": new ObjectId('55f16640a17eed480bb0dc18')},
{"messages": {$elemMatch:{"_id": new ObjectId('55fc60bc260c9be5879ef733')}}}
).pretty();
The above query should return the _id field (same as appears in the query clause), and the array element whose id is mentioned in the projection clause
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With