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

Compound multikey index does not compound indexbounds when nested in an object

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.6.10, 2.6.11
    • Component/s: Index Maintenance
    • None
    • ALL
    • Hide

      #Unbound predicate scenario

      use test_db;
      db.c.drop();
      db.c.save({nest: {a:'hello', b: ['hello', 'world']}});
      db.c.save({nest: {a:'world', b: ['hello', 'world']}});
      db.c.ensureIndex({"nest.a":1, "nest.b":1});
      db.c.find({"nest.a": 'hello', "nest.b": 'world'}).explain();
      
      //Working scenario (non-nested)
      use test_db;
      db.c.drop();
      db.c.save({a: 'hello', b: ['hello', 'world']});
      db.c.save({a: 'world', b: ['hello', 'world']});
      db.c.ensureIndex({"a":1, "b":1});
      db.c.find({"a": 'hello', "b": "world"}).explain();
      
      Show
      #Unbound predicate scenario use test_db; db.c.drop(); db.c.save({nest: {a:'hello', b: ['hello', 'world']}}); db.c.save({nest: {a:'world', b: ['hello', 'world']}}); db.c.ensureIndex({"nest.a":1, "nest.b":1}); db.c.find({"nest.a": 'hello', "nest.b": 'world'}).explain(); //Working scenario (non-nested) use test_db; db.c.drop(); db.c.save({a: 'hello', b: ['hello', 'world']}); db.c.save({a: 'world', b: ['hello', 'world']}); db.c.ensureIndex({"a":1, "b":1}); db.c.find({"a": 'hello', "b": "world"}).explain();

      When creating a compound multikey index on a string- and an array field (both nested inside the same object) the indexbounds is constrained to only the leading field in the index.

      This behavior doesn't occur when the string and array fields are at the root level. During a query on both fields, both predicates are compounded in the index bound.

      Eg:
      Given the following structure:

      {nest: {a:'hello', b: ['hello', 'world']}}
      

      We add a compound index on `nest.a` an `nest.b`
      When we query for both `nest.a` and `nest.b`, the index is not bound for the predicate `nest.b`

       db.c.find({"nest.a": 'hello', "nest.b": 'world'}).explain();
      {
      	"cursor" : "BtreeCursor nest.a_1_nest.b_1",
      	"isMultiKey" : true,
      	"n" : 1,
      	"nscannedObjects" : 2,
      	"nscanned" : 2,
      	"nscannedObjectsAllPlans" : 2,
      	"nscannedAllPlans" : 2,
      	"scanAndOrder" : false,
      	"indexOnly" : false,
      	"nYields" : 0,
      	"nChunkSkips" : 0,
      	"millis" : 0,
      	"indexBounds" : {
      		"nest.a" : [
      			[
      				"hello",
      				"hello"
      			]
      		],
      		"nest.b" : [
      			[
      				{
      					"$minElement" : 1
      				},
      				{
      					"$maxElement" : 1
      				}
      			]
      		]
      	},
      	"server" : "....."
      }
      

      However, if we assume the same structure but move it out of the object both predicates are bound.

      {a: 'hello', b: ['hello', 'world']}
      
      db.c.find({"a": 'hello', "b": "world"}).explain();
      {
      	"cursor" : "BtreeCursor a_1_b_1",
      	"isMultiKey" : true,
      	"n" : 1,
      	"nscannedObjects" : 1,
      	"nscanned" : 1,
      	"nscannedObjectsAllPlans" : 1,
      	"nscannedAllPlans" : 1,
      	"scanAndOrder" : false,
      	"indexOnly" : false,
      	"nYields" : 0,
      	"nChunkSkips" : 0,
      	"millis" : 0,
      	"indexBounds" : {
      		"a" : [
      			[
      				"hello",
      				"hello"
      			]
      		],
      		"b" : [
      			[
      				"world",
      				"world"
      			]
      		]
      	},
      	"server" : "...."
      }
      

      Is this expected behavior? I couldn't find anything in the docs that points to limitations of nested compound multikey indexes.

            Assignee:
            kelsey.schubert@mongodb.com Kelsey Schubert
            Reporter:
            wernerj101 Werner Smit
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: