David
David

Reputation: 1356

Multiple $elemMatch in one query

My basic structure is this for a user:

{name : 'name',
lists : [
    {id : 'xyz',
    items : [
        {name : 'itemName',
         purchased : false
        } 
        ]
    }]
}

I want to write a query where I can update itemName's purchased Bool. I am able to get the list of items out using elemMatch, but I can't seem to select the item with the name of itemName.

Essentially, what I want is lists.$.gifts.$.purchased = true.

Is there a way to do this? It would be great if it could be done in one query, but if not, can it be done at all?

Upvotes: 0

Views: 1215

Answers (1)

Sarath Nair
Sarath Nair

Reputation: 2868

You cannot use multiple projection operator ($) in a query. The positional operator only supports one level nesting and also it matches the first element.

There is a JIRA ticket on this: https://jira.mongodb.org/browse/SERVER-831

In your case what you can do is do a find query to retrieve the document.

{
  name : 'name',
  lists : [
   {
     id : 'xyz',
     items : [
       {
         name : 'itemName',
         purchased : false
       } 
     ]
   }
  ]
}

From the above json document, iterate the lists and items array to get the index of array element. From your document you can see like the array index is 0. You can then do a straight ahead update query of following form:

db.collection.update(
  {name:'name'},
  {$set:{'lists.0.items.0.purchased': true}}
)

or if you know the id in lists array, then you can fine tune the above query using positional operator,

db.collection.update(
  {name:'name','lists.id':'xyz'},
  {$set:{'lists.$.items.0.purchased': true}}
)

I hope this answers your question.

Upvotes: 1

Related Questions