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

Combine index ranges for dotted fields within a $elemMatch expression, when possible

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.3.0
    • Component/s: Performance, Querying
    • Labels:
      None
    • Environment:
      Ubuntu 12.04 LTS
    • Fully Compatible
    • ALL

      Implement the SERVER-3104 optimization for dotted field cases where it can be supported. Note that it cannot be supported in some cases such as the following:

      // Cases with double dotted index field names.
      t.drop();
      index = { 'a.b.x':1, 'a.b.y':1 };
      t.ensureIndex( index );
      t.save( { a:{ b:{ x:1, y:1 } } } );
      t.save( { a:[ { b:{ x:1 } }, { b:{ y:1 } } ] } );
      t.save( { a:[ { b:[ { x:1 }, { y:1 } ] } ] } );
      t.save( { a:[ { b:[ { x:1, y:1 } ] } ] } );
      assert.eq( 4, t.count() );
      // No $elemMatch.
      assertResultsAndIndexBounds( { 'a.b.x':[[ 1, 1 ]], 'a.b.y':[[ MIN, MAX ]] },
                                   { 'a.b.x':1, 'a.b.y':1 } );
      // $elemMatch with dotted children.
      assertResultsAndIndexBounds( { 'a.b.x':[[ 1, 1 ]], 'a.b.y':[[ MIN, MAX ]] },
                                   { a:{ $elemMatch:{ 'b.x':1, 'b.y':1 } } } );
      // $elemMatch with undotted children.
      assertResultsAndIndexBounds( { 'a.b.x':[[ 1, 1 ]], 'a.b.y':[[ 1, 1 ]] },
                                   { 'a.b':{ $elemMatch:{ x:1, y:1 } } } );
      

      Aaron

      -----------------------------------------------------------

      the SERVER-3104 optimization will not work correctly when there are dotted fields within a $elemMatch expression

       
      db.test.insert({"code" : "000001", doc : [ {"code1" : "000001", "type" : { "subtype" : [ "1" ,"3" ]}}]});
      db.test.insert({"code" : "000002", doc : [ {"code1" : "000001", "type" : { "subtype" : [ "1" ]}}]});
      db.test.insert({"code" : "000003", doc : [ {"code1" : "000001", "type" : { "subtype" : [ "1", "2"] }}]});
      db.test.insert({"code" : "000004", doc : [ {"code1" : "000001", "type" : { "subtype" : [ "2" ]}}, {"code1" : "000002", "type" : { "subtype" : [ "3" ]}} ]});
      db.test.insert({"code" : "000005", doc : [ {"code1" : "000001", "type" : { "subtype" : [ ]}}]});
      db.test.insert({"code" : "000006", doc : [ {"code1" : "000001", "type" : { "subtype" : [ "3" ]}}]});
      db.test.insert({"code" : "000007", doc : [ {"code1" : "000001" }]});
       
      db.test.insert({"code" : "000001", doc : [ {"code1" : "000002", "type" : { "subtype" : [ "1" ,"3" ]}}]});
      db.test.insert({"code" : "000002", doc : [ {"code1" : "000002", "type" : { "subtype" : [ "1" ]}}]});
      db.test.insert({"code" : "000003", doc : [ {"code1" : "000002", "type" : { "subtype" : [ "1", "2"] }}]});
      db.test.insert({"code" : "000004", doc : [ {"code1" : "000002", "type" : { "subtype" : [ "2" ]}}, {"code1" : "000001", "type" : { "subtype" : [ "3" ]}} ]});
      db.test.insert({"code" : "000005", doc : [ {"code1" : "000002", "type" : { "subtype" : [ ]}}]});
      db.test.insert({"code" : "000006", doc : [ {"code1" : "000002", "type" : { "subtype" : [ "3" ]}}]});
      db.test.insert({"code" : "000007", doc : [ {"code1" : "000002" }]});
       
      db.test.insert({"code" : "000001", doc : [ {"code1" : "000003", "type" : { "subtype" : [ "1" ,"3" ]}}]});
      db.test.insert({"code" : "000002", doc : [ {"code1" : "000003", "type" : { "subtype" : [ "1" ]}}]});
      db.test.insert({"code" : "000003", doc : [ {"code1" : "000003", "type" : { "subtype" : [ "1", "2"] }}]});
      db.test.insert({"code" : "000004", doc : [ {"code1" : "000003", "type" : { "subtype" : [ "2" ]}}]});
      db.test.insert({"code" : "000005", doc : [ {"code1" : "000003", "type" : { "subtype" : [ ]}}]});
      db.test.insert({"code" : "000006", doc : [ {"code1" : "000003", "type" : { "subtype" : [ "3" ]}}]});
      db.test.insert({"code" : "000007", doc : [ {"code1" : "000003" }]});
      db.test.ensureIndex( { "doc.code1": 1, "doc.type.subtype": -1, "code": -1 }, { unique: false, sparse: false, background: true, name: "index_test"} )
       
      db.test.find( { "doc" : { "$elemMatch" : { "code1" : { "$in" :[ "000001", "000003" ] }, "type.subtype" : "2" } } } ).explain()
      {
          "cursor" : "BtreeCursor index_test multi",
          "isMultiKey" : true,
          "n" : 4,
          "nscannedObjects" : 19,
          "nscanned" : 20,
          "nscannedObjectsAllPlans" : 39,
          "nscannedAllPlans" : 40,
          "scanAndOrder" : false,
          "indexOnly" : false,
          "nYields" : 0,
          "nChunkSkips" : 0,
          "millis" : 0,
          "indexBounds" : {
              "doc.code1" : [
                  [
                      "000001",
                      "000001"
                  ],
                  [
                      "000003",
                      "000003"
                  ]
              ],
              "doc.type.subtype" : [
                  [
                      {
                          "$maxElement" : 1
                      },
                      {
                          "$minElement" : 1
                      }
                  ]
              ],
              "code" : [
                  [
                      {
                          "$maxElement" : 1
                      },
                      {
                          "$minElement" : 1
                      }
                  ]
              ]
          },
          "server" : "xxx:27017"
      }
      

            Assignee:
            david.storch@mongodb.com David Storch
            Reporter:
            lucas.pouzac.pro Lucas Pouzac
            Votes:
            3 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: