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

Covered query for $replaceRoot involving missing fields returns different results than collection scan

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Query
    • ALL
    • Hide
      python buildscripts/resmoke.py --storageEngine wiredTiger --suites aggregation repro_match_replace_root.js
      
      repro_match_replace_root.js
      assert.commandWorked(db.my_coll.insert({}));
      
      const res1 = db.my_coll
      	.aggregate([
      		{
      			$match: {
      				a: { 
      					$not: { 
      						$gte: 5
      					}
      				}
      			}
      		},
      		{
      			$replaceRoot: {
      				newRoot:{
      					v: '$a'
      				}
      			}
      		},
      ]).toArray();
      
      assert.commandWorked(db.my_coll.createIndex({a:1}));
      
      const res2 = db.my_coll
      	.aggregate([
      		{
      			$match: {
      				a: { 
      					$not: { 
      						$gte: 5
      					}
      				}
      			}
      		},
      		{
      			$replaceRoot: {
      				newRoot:{
      					v: '$a'
      				}
      			}
      		},
      ]).toArray();
      
      assert.eq(res1, res2);
      
      Show
      python buildscripts/resmoke.py --storageEngine wiredTiger --suites aggregation repro_match_replace_root.js repro_match_replace_root.js assert.commandWorked(db.my_coll.insert({})); const res1 = db.my_coll .aggregate([ { $match: { a: { $not: { $gte: 5 } } } }, { $replaceRoot: { newRoot:{ v: '$a' } } }, ]).toArray(); assert.commandWorked(db.my_coll.createIndex({a:1})); const res2 = db.my_coll .aggregate([ { $match: { a: { $not: { $gte: 5 } } } }, { $replaceRoot: { newRoot:{ v: '$a' } } }, ]).toArray(); assert.eq(res1, res2);
    • 9

      When no index is present and $match is called before a $replaceRoot that uses the same index, it will do a collection scan and $replaceRoot will return an empty document. However, when the index is present but the field doesn't exist in the document, the query system ends up performing a covered query. The index has a null entry for the document because the field doesn't exist in the document. This causes $replaceRoot to return a non-empty document with the missing field associated with a literal null value.

      [js_test:repro_match_replace_root] 2019-07-31T18:09:25.364-0400 2019-07-31T18:09:25.363-0400 E  QUERY    [js] uncaught exception: Error: [[ { } ]] != [[ { "v" : null } ]] are not equal :
      [js_test:repro_match_replace_root] 2019-07-31T18:09:25.364-0400 doassert@src/mongo/shell/assert.js:20:14
      [js_test:repro_match_replace_root] 2019-07-31T18:09:25.364-0400 assert.eq@src/mongo/shell/assert.js:180:9
      [js_test:repro_match_replace_root] 2019-07-31T18:09:25.364-0400 @repro_match_replace_root.js:45:1
      [js_test:repro_match_replace_root] 2019-07-31T18:09:25.364-0400 2019-07-31T18:09:25.363-0400 F  -        [main] failed to load: repro_match_replace_root.js
      [js_test:repro_match_replace_root] 2019-07-31T18:09:25.364-0400 2019-07-31T18:09:25.363-0400 E  -        [main] exiting with code -3
      

            Assignee:
            backlog-server-query Backlog - Query Team (Inactive)
            Reporter:
            sandy.gould@mongodb.com Sandra Gould (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: