[SERVER-22246] Objects are no longer treated as literals inside of an array of an aggregation expression Created: 20/Jan/16  Updated: 02/Feb/16  Resolved: 02/Feb/16

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

Type: Bug Priority: Critical - P2
Reporter: Jesse English Assignee: Benjamin Murphy
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Steps To Reproduce:

STEP ONE: Set up a collection (e.g. named j_bug) with the following two documents:

{ 
    "_id" : ObjectId("569fbe30f6916b01e49b27b7"), 
    "rand" : NumberInt(456), 
    "entities" : [
        {
            "name" : "Test Entity"
        }
    ]
}
{ 
    "_id" : ObjectId("569fbe8cf6916b01e49b27b9"), 
    "rand" : NumberInt(123)
}

STEP TWO: in mongo version 3.2.1 run the following aggregation

db.j_bug.aggregate([
{$project:{entities:{$ifNull:["$entities", [  {'name' : 'No Entity'} ] ]}}}
])
>>Error from description will be produced.

In mongo version 3.0.7 run the exact same aggregation query and you should get the desired output as follows:

{ "_id" : ObjectId("569fbe30f6916b01e49b27b7"), "entities" : [ { "name" : "Test Entity" } ] }
{ "_id" : ObjectId("569fbe8cf6916b01e49b27b9"), "entities" : [ { "name" : "No Entity" } ] }

Participants:

 Description   

On 3.0, an expression like the following will work:

{ $project: { _id: 0, entities:{ $ifNull : [ '$entities', [  {'name' : 'No Entity'} ] ] } }

but on 3.2.1, it will generate the following error, since it tries to interpret the object literal {name: 'No Entity'} as an expression:

assert: command failed: {
	"ok" : 0,
	"errmsg" : "field inclusion is not allowed inside of $expressions",
	"code" : 16420
} : aggregate failed
_getErrorWithCode@src/mongo/shell/utils.js:23:13
doassert@src/mongo/shell/assert.js:13:14
assert.commandWorked@src/mongo/shell/assert.js:266:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1215:5
@(shell):1:1
 
2016-01-20T13:02:55.869-0400 E QUERY    [thread1] Error: command failed: {
	"ok" : 0,
	"errmsg" : "field inclusion is not allowed inside of $expressions",
	"code" : 16420
} : aggregate failed :
_getErrorWithCode@src/mongo/shell/utils.js:23:13
doassert@src/mongo/shell/assert.js:13:14
assert.commandWorked@src/mongo/shell/assert.js:266:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1215:5
@(shell):1:1

The workaround is to wrap the object in a $literal expression, like so:

{ $project: { _id: 0, entities:{ $ifNull : [ '$entities', [  {$literal: {'name' : 'No Entity'} } ] ] } }



 Comments   
Comment by Charlie Swanson [ 02/Feb/16 ]

Hi jesse_english,

This was actually described in the compatibility changes section of our 3.2 release notes.

We have decided not to fix this, since there is an easy workaround, and the change that introduced this regression was valuable in that it made new types of computations possible.

Comment by Charlie Swanson [ 27/Jan/16 ]

Hi jesse_english,

Thank you for the report. I've updated the description and title to be a bit more broad to encompass all the cases this might impact. I will update the ticket when we have more news.

Comment by Charlie Swanson [ 22/Jan/16 ]

I believe this was an unpredicted backwards breaking change introduced via SERVER-8141. I will need to do some more investigation to see if we can fix it without reverting SERVER-8141, but I am hopeful that we can. In the meantime, the workaround is to wrap it in a literal like so:

db.j_bug.aggregate([
{$project:{entities:{$ifNull:["$entities", [  {$literal: {'name' : 'No Entity'}} ] ]}}}
])

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