Hi
The more I look into MongoDB, the more Im confused by how MongoDB matches dictionaries fields.
Exact match and partial match of fields
It is not always explicit and sometimes tricky to guess if MongoDB will match the document only if all the fields are present (exact match) or if the fields described are a subset of the fields of the docuement (partial match).
Example on subdocuments
> db.test.insert({a:{a:1}}); > db.test.insert({a:{a:1,b:2}}); > db.test.insert({a:{a:1,b:2,c:3}}); > db.test.find({'a.a':1,'a.b':2}); // partial match {a:{a:1,b:2}} {a:{a:1,b:2,c:3}} > db.test.find({a:{a:1,b:2}}); // exact match {a:{a:1,b:2}}
Example on array items
> db.test.insert({a:[{a:1}]}); > db.test.insert({a:[{a:1,b:2}}}); > db.test.insert({a:[{a:1,b:2,c:3}]}); > db.test.find({a:{$elemMatch:{a:1,b:2}}}); // partial match {a:[{a:1,b:2}]} {a:[{a:1,b:2,c:3}]} > db.test.find({a:{a:1,b:2}}); // exact match {a:[{a:1,b:2}]}
Example on documents
> db.test.insert({a:1}); > db.test.insert({a:1,b:2}); > db.test.insert({a:1,b:2,c:3}); > db.test.find({'a':1,'b':2}); // partial match {a:1,b:2} {a:1,b:2,c:3} > db.test.find({'':{a:1,b:2}}); // exact match ??? // Does not work :(
Order of the fields
The second point is that the order of the fields sometimes matters, sometimes not.
Example, the order matters when searching with exact match
> db.test.insert({a:{a:1,b:2}});
> db.test.insert({a:{b:2,a:1}});
> db.test.find({a:{a:1,b:2}}); // order matters
{a:{a:1,b:2}}
Example, the order does not matter when updating (or not)
> db.test.insert({a:{b:2,a:1}}); > db.test.update({}, {$set:{'a.b':'foo'}}); // reorders > db.test.find(); {a:{a:1,b:'foo'}}
> db.test.insert({a:{b:2,a:1}}); > db.test.update({}, {$set:{'a.b':3}}); // keeps the order > db.test.find(); {a:{b:3,a:1}}
> db.test.insert({a:{b:2,a:1}}); > db.test.update({}, {$set:{'a.c':'foo'}}); // reorders > db.test.find(); {a:{a:1,b:2,c:'foo'}}
So on update, if the size of the object changes, fields are reordered in the alphabetic order (and '_id' is first). The first case could keep the order, but the last one is a bit more tricky, so keep the order on updates is not a simple thing.
What to do ?
My point is :
- partial or exact matching is not explicit, and exact matching on documents is impossible
- order matters on exact matching, but can be changed by updates
First, a full section about these points should be included in the documentation to avoid surprises
Second, the solution I see are 3 operators which make explicit which match id done. For instance :
- $partial makes explict partial matching
- $ordered makes explicit exact ordered matching
- $unordered makes explicit exact unordered matching
Their name do not really matter, but I would like to have explicit operators to be sure for once of how my requests will be interpreted.
Thank you