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

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Duplicate
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Operating System:
      ALL
    • Steps To Reproduce:
      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);
    • Linked BF Score:
      0

      Description

      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
      

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                Created:
                Updated:
                Resolved: