Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-12617

operators for explicit partial, exact ordered and unordered matching on dictionaries fields

      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

            Assignee:
            Unassigned Unassigned
            Reporter:
            theshuss aurelien lambert
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: