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

Aggregation's renamed fields analysis is broken for dotted field paths, causes incorrect query results

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Critical - P2 Critical - P2
    • 3.6.0-rc3
    • Affects Version/s: 3.6.0-rc0
    • Component/s: Aggregation Framework
    • Labels:
      None
    • Fully Compatible
    • ALL
    • Query 2017-11-13

      The optimization added in SERVER-27115 to allow index usage in the case of a renamed field is broken for matches on a dotted field path. See the example below. This is a regression introduced during 3.5 development. The 3.6 release candidates are affected, but no pre-existing stable release series is affected.

      > db.c.drop();
      true
      > db.c.insert({x: [{y: 1}, {y: 2}]});
      WriteResult({ "nInserted" : 1 })
      
      // Match with no dotted field path returns the correct result. The explain indicates that
      // the $match stage swapped in front of the $addFields, and was absorbed into the
      // $cursor stage after being correctly renamed to a match on "x".
      > db.c.aggregate([{$addFields: {z: "$x"}}, {$match: {z: {y: 1}}}]);
      { "_id" : ObjectId("59ef5d62b49385b9971e2c09"), "x" : [ { "y" : 1 }, { "y" : 2 } ], "z" : [ { "y" : 1 }, { "y" : 2 } ] }
      > db.c.explain().aggregate([{$addFields: {z: "$x"}}, {$match: {z: {y: 1}}}]);
      {
      	"stages" : [
      		{
      			"$cursor" : {
      				"query" : {
      					"x" : {
      						"$eq" : {
      							"y" : 1
      						}
      					}
      				},
      				"queryPlanner" : {
      					"plannerVersion" : 1,
      					"namespace" : "test.c",
      					"indexFilterSet" : false,
      					"parsedQuery" : {
      						"x" : {
      							"$eq" : {
      								"y" : 1
      							}
      						}
      					},
      					"winningPlan" : {
      						"stage" : "COLLSCAN",
      						"filter" : {
      							"x" : {
      								"$eq" : {
      									"y" : 1
      								}
      							}
      						},
      						"direction" : "forward"
      					},
      					"rejectedPlans" : [ ]
      				}
      			}
      		},
      		{
      			"$addFields" : {
      				"z" : "$x"
      			}
      		}
      	],
      	"ok" : 1
      }
      
      // When a similar match is expressed using the dotted path "z.y", the matching document
      // is incorrectly omitted from the result set. The explain indicates that the rename to "x.y"
      // was not applied correctly.
      > db.c.explain().aggregate([{$addFields: {z: "$x"}}, {$match: {"z.y": 1}}]);
      {
      	"stages" : [
      		{
      			"$cursor" : {
      				"query" : {
      					"z.y" : {
      						"$eq" : 1
      					}
      				},
      				"queryPlanner" : {
      					"plannerVersion" : 1,
      					"namespace" : "test.c",
      					"indexFilterSet" : false,
      					"parsedQuery" : {
      						"z.y" : {
      							"$eq" : 1
      						}
      					},
      					"winningPlan" : {
      						"stage" : "COLLSCAN",
      						"filter" : {
      							"z.y" : {
      								"$eq" : 1
      							}
      						},
      						"direction" : "forward"
      					},
      					"rejectedPlans" : [ ]
      				}
      			}
      		},
      		{
      			"$addFields" : {
      				"z" : "$x"
      			}
      		}
      	],
      	"ok" : 1
      }
      

            Assignee:
            justin.seyster@mongodb.com Justin Seyster
            Reporter:
            david.storch@mongodb.com David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: