Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to remove "tag4" only for "user3":

{
  _id: "doc"
  some: "value",
  users: [
    {
      _id: "user3",
      someOther: "value",
      tags: [
        "tag4",
        "tag2"
      ]
    }, {
      _id: "user1",
      someOther: "value",
      tags: [
        "tag3",
        "tag4"
      ]
    }
  ]
},
{
  ...
}

Note: This collection holds items referencing many users. Users are stored in a different collection. Unique tags for each user are also stored in the users collection. If an user removes a tag (or multiple) from his account it should be deleted from all items.

I tried this query, but it removes "tag4" for all users:

{
  "users._id": "user3",
  "users.tags": {
    $in: ["tag4"]
  }
}, {
  $pullAll: {
    "users.$.tags": ["tag4"]
  }
}, {
  multi: 1
}

I tried $elemMatch (and $and) in the selector but ended up with the same result only on the first matching document or noticed some strange things happen (sometimes all tags of other users are deleted).

Any ideas how to solve this? Is there a way to "back reference" in $pull conditions?

share|improve this question

1 Answer 1

up vote 0 down vote accepted

You need to use $elemMatch in your query object so that it will only match if both the _id and tags parts match for the same element:

db.test.update({
  users: {$elemMatch: {_id: "user3", tags: {$in: ["tag4"]}}}
}, {
  $pullAll: {
    "users.$.tags": ["tag4"]
  }
}, {
  multi: 1
})
share|improve this answer
    
I use coffeescript, fixed it. This query does not work as intended. If you run it when only "user1" has "tag4", "tag4" is removed for "user1". (strange: sometimes all tags for "user1" are removed) –  timw Nov 30 '13 at 15:14
    
@timw Ah, see updated answer. –  JohnnyHK Nov 30 '13 at 15:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.