5

Given the following JSON example:

{
    _id: "55ef729a66d78d24008xxxx",
    name: "The right one"
    items: [{
        _id: "55ef729a66d78d24008xxxx",
        return: true
    }, {
        _id: "55ef729a66d78d24008xxxx",
        return: true
    }, {
        _id: "55ef729a66d78d24008xxxx",
        return: false
    }]
}

I want to write a query that specifies items.return = true and it should return:

{
    _id: "55ef729a66d78d24008xxxx",
    name: "The right one"
    items: [// 2 element array]
}

I've seen a lot of people suggest using $elemMatch, such as this question, but as it says, this

only return the first match

but this just returns the parent documents that have some value in the array matching items.return. So in the above example it would return all 3 array elements.

I want to completely ignore these array values in my return. I don't want to do it in the client, because I do a project using the items _id and don't want to waste the project if I don't need it.

Community
  • 1
  • 1
KJ3
  • 5,168
  • 4
  • 33
  • 53
  • Different question, that question refers to returning parent documents with the exact arrays that match, I need to alter the array itself. – KJ3 Oct 26 '15 at 19:08
  • It's not about the question but the **answers** provided to the question. There are several answers there that use the aggregation framework to return just the matched "elements" as that is the only tool ( aside from map reduce ) that is able to do so. – Blakes Seven Oct 26 '15 at 20:32

3 Answers3

3

Alternative not exact you want

db.items.aggregate(
      {$unwind:"$items"},
      {$match:{"items.return":true}}
)
Alok Deshwal
  • 1,128
  • 9
  • 20
2

One alternative is to use $elemMatch. Check the docs, worth to notice is that it only returns first match!

db.items.find({}, {items: {$elemMatch: {return: "admin"}}}});
jano
  • 735
  • 7
  • 20
mirwaleed
  • 69
  • 7
  • 1
    **From review queue**: May I request you to please add some context around your source-code. Code-only answers are difficult to understand. It will help the asker and future readers both if you can add more information in your post. – RBT May 15 '17 at 23:54
1

You can use the aggregation framework, it is not the best solution though

db.collection.aggregate([
      {$unwind:'$items'},
      {$match:{'items.return':true}},
      {$group:{_id:'$_id', name: '$name',items:{$push:'$items'}}}
])
Frol
  • 34
  • 3