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

Track fields renamed by $project in aggregation for index consideration

    • Fully Compatible
    • ALL
    • Hide
      > db.version()
      3.4.0-rc1
      > c.createIndex({x:1})
      {
      	"createdCollectionAutomatically" : false,
      	"numIndexesBefore" : 1,
      	"numIndexesAfter" : 2,
      	"ok" : 1
      }
      > c.explain().aggregate([{$project:{x_renamed:"$x"}},{$match:{"x_renamed" : 1}}])
      {
      	"stages" : [
      		{
      			"$cursor" : {
      				"query" : {
      					
      				},
      				"fields" : {
      					"x" : 1,
      					"_id" : 1
      				},
      				"queryPlanner" : {
      					"plannerVersion" : 1,
      					"namespace" : "test.col",
      					"indexFilterSet" : false,
      					"parsedQuery" : {
      						
      					},
      					"winningPlan" : {
      						"stage" : "COLLSCAN",
      						"direction" : "forward"
      					},
      					"rejectedPlans" : [ ]
      				}
      			}
      		},
      		{
      			"$project" : {
      				"_id" : true,
      				"x_renamed" : "$x"
      			}
      		},
      		{
      			"$match" : {
      				"x_renamed" : 1
      			}
      		}
      	],
      	"ok" : 1
      }
      >
      >//Compared to $matching on the original field name (after SERVER-19153)
      >
      > c.explain().aggregate([{$project:{x:1}},{$match:{"x" : 1}}])
      {
      	"stages" : [
      		{
      			"$cursor" : {
      				"query" : {
      					"x" : 1
      				},
      				"fields" : {
      					"x" : 1,
      					"_id" : 1
      				},
      				"queryPlanner" : {
      					"plannerVersion" : 1,
      					"namespace" : "test.col",
      					"indexFilterSet" : false,
      					"parsedQuery" : {
      						"x" : {
      							"$eq" : 1
      						}
      					},
      					"winningPlan" : {
      						"stage" : "FETCH",
      						"inputStage" : {
      							"stage" : "IXSCAN",
      							"keyPattern" : {
      								"x" : 1
      							},
      							"indexName" : "x_1",
      							"isMultiKey" : false,
      							"multiKeyPaths" : {
      								"x" : [ ]
      							},
      							"isUnique" : false,
      							"isSparse" : false,
      							"isPartial" : false,
      							"indexVersion" : 2,
      							"direction" : "forward",
      							"indexBounds" : {
      								"x" : [
      									"[1.0, 1.0]"
      								]
      							}
      						}
      					},
      					"rejectedPlans" : [ ]
      				}
      			}
      		},
      		{
      			"$project" : {
      				"_id" : true,
      				"x" : true
      			}
      		}
      	],
      	"ok" : 1
      }
      
      Show
      > db.version() 3.4.0-rc1 > c.createIndex({x:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > c.explain().aggregate([{$project:{x_renamed:"$x"}},{$match:{"x_renamed" : 1}}]) { "stages" : [ { "$cursor" : { "query" : { }, "fields" : { "x" : 1, "_id" : 1 }, "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.col", "indexFilterSet" : false, "parsedQuery" : { }, "winningPlan" : { "stage" : "COLLSCAN", "direction" : "forward" }, "rejectedPlans" : [ ] } } }, { "$project" : { "_id" : true, "x_renamed" : "$x" } }, { "$match" : { "x_renamed" : 1 } } ], "ok" : 1 } > >//Compared to $matching on the original field name (after SERVER-19153) > > c.explain().aggregate([{$project:{x:1}},{$match:{"x" : 1}}]) { "stages" : [ { "$cursor" : { "query" : { "x" : 1 }, "fields" : { "x" : 1, "_id" : 1 }, "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.col", "indexFilterSet" : false, "parsedQuery" : { "x" : { "$eq" : 1 } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "x" : 1 }, "indexName" : "x_1", "isMultiKey" : false, "multiKeyPaths" : { "x" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "x" : [ "[1.0, 1.0]" ] } } }, "rejectedPlans" : [ ] } } }, { "$project" : { "_id" : true, "x" : true } } ], "ok" : 1 }
    • Query 2017-03-27, Query 2017-04-17, Query 2017-05-08, Query 2017-05-29, Query 2017-06-19
    • 0

      Simply renaming a field in a $project currently disqualifies it from index consideration. The database should track simple field name changes in order to preserve index options.

      This is particularly relevant since SERVER-19153 has been implemented and views are being introduced. In addition to BI use cases, consider that views would allow for more compact field names be stored in the collection and then expanded out via the view definition (eg: fn -> firstname).

      Implementation of this feature would allow for more flexibility in how logically equivalent aggregation pipelines are written while optimal performance is maintained.

            Assignee:
            david.storch@mongodb.com David Storch
            Reporter:
            christopher.harris@mongodb.com Chris Harris
            Votes:
            0 Vote for this issue
            Watchers:
            14 Start watching this issue

              Created:
              Updated:
              Resolved: