[SERVER-16151] Document array behaviour in aggregate pipelines. Created: 14/Nov/14  Updated: 05/Dec/14  Resolved: 14/Nov/14

Status: Closed
Project: Core Server
Component/s: Aggregation Framework
Affects Version/s: 2.6.5
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Jeroen Cranendonk Assignee: Ramon Fernandez Marina
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Participants:

 Description   

The following confuses me:

Data:

db.foo.insert({name: "Hello"})

Operation:

db.foo.aggregate({$project: { "_id": 0, "Hello" : {$map: {input: ["$name"],  as: "whee", in: "$$whee"} } }})

Result:

{ "Hello" : [ "$name" ] }

Somehow I would have expected $name to be expanded to "Hello".
I'm sure there's a good reason that doesn't happen, but I couldn't find anything on the site that explains exactly what's going on here



 Comments   
Comment by Ramon Fernandez Marina [ 14/Nov/14 ]

As per the documentation for $map, input needs to be an expression that resolves to an array. In your example, your input is an array that contains one element, namely the string "$name" – but this is no longer a field path.

Changing the name field to be an array does the trick:

> db.foo.drop()
> db.foo.insert({name:["Hello"]})
WriteResult({ "nInserted" : 1 })
> db.foo.aggregate({$project: { "_id": 0, x : {$map: {input: "$name",  as: "whee", in: "$$whee"} } }})
{ "x" : [ "Hello" ] }

If you prefer not to change your schema you can always build the array to use as the input for $map; here's an example using $addToSet:

> db.foo.aggregate(
  {$group : {
    _id : "$_id",
    mapinput : {$addToSet:"$name"}}
  },
  {$project : {
    "_id" : 0,
    x : {$map: {input: "$mapinput",  as: "whee", in: "$$whee"} }
  }
})
{ "x" : [ "Hello" ] }

Generated at Thu Feb 08 03:40:07 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.