Вопрос

Im looking for a way in MongoDB to find an exact document, meaning that I dont want to match document with other fields than the ones expected.

This is what I can do on subdocuments

> db.test.insert({a:{b:1,c:2}});
> db.test.insert({a:{b:1}});
> db.test.find({'a.b':1}); // non exact match
{a:{b:1,c:2}}
{a:{b:1}}
> db.test.find({'a':{'b':1}}); // exact match
{a:{b:1}}

I'd like to do the same on the main document (not a subdocument). But

> db.test.insert({b:1,c:2});
> db.test.insert({b:1});
> db.test.find({'b':1}); // non exact match
{a:{b:1,c:2}}
{a:{b:1}}
> db.test.find({'.':{'b':1}}); // does not work :(
> db.test.find({'b':1, 'c':null}); // works, but how I am supposed to know that 'c' could exists ???
{a:{b:1}}

The final goal being to do this with $pull on arrays

> db.test.insert({a:[{b:1,c:2},{b:1,d:3},{b:1,c:2},{b:1,c:2,d:3}]});
> db.test.update({}, {$pull:{'a':{b:1,c:2}}});
> db.test.find();
{a:[{b:1,d:3}]} // NOOOO :'(

Has anybody an idea about it ?

edit :

Here are some precision on exact / partial matching I found on arrays :

  • array item exact matching : db.test.find({'a':{b:1,c:2}});
  • array item partial matching : db.test.find({'a':{$elemMatch:{b:1,c:2}}});
  • array item removal partial matching : db.test.update({}, {$pull:{'a':{b:1,c:2}}})
  • array item removal exact matching : db.test.update({}, {$pullAll:{'a':[{b:1,c:2}]}}) (thanks to JohnnyHK)
Это было полезно?

Решение

It's not well documented, but if you use $pullAll instead of $pull, only the exactly matching elements are removed:

db.test.update({}, {$pullAll:{a: [{b:1,c:2}]}});
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top