[SERVER-67030] `$getField` doesn't work with a dynamic `field` Created: 06/Jun/22  Updated: 27/Oct/23  Resolved: 21/Jun/22

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: 5.0.9
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Boris Petrov Assignee: Anton Korshunov
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to SERVER-74371 Support arbitrary expressions for 'fi... Closed
Operating System: ALL
Participants:

 Description   

 

db.test.insert({ a: 'a' });
db.test.aggregate([{ $addFields: { result: { $getField: { field: { $concat: ['$a', 'a'] }, input: { aa: 1 } } } } }]);

This leads to:

 

MongoServerError: Invalid $addFields :: caused by :: $getField requires 'field' to evaluate to a constant, but got a non-constant argument

I don't understand why that happens (and believe it's a bug). According to getField's documentation `field` can be any expression that resolves to a string. In my example it is such but it doesn't work.

 

 



 Comments   
Comment by Boris Petrov [ 22/Jun/22 ]

Done!

Comment by Chris Kelly [ 21/Jun/22 ]

Thank you Anton for clarification on that! I didn't catch the constant part of the field description.

alien, in this case, you can actually go ahead and go to feedback.mongodb.com to submit this as a feature request if you like. Thanks for your report!

Christopher

Comment by Boris Petrov [ 21/Jun/22 ]

Anton, thank you for the information! I didn't expect "constant" to literally mean constant at "compile" time as that's perhaps the only place in MongoDB's query language where such a restriction exists. It would be nice if it is lifted at some point (even with a performance-penalty). I guess you can change this ticket to be a feature-request one instead of a bug.

Thanks again for the time!

Comment by Anton Korshunov [ 21/Jun/22 ]

alien The $getField expression in this particular examples works as designed. Note that our documentation says:

Field in the input object for which you want to return a value. field can be any valid expression that resolves to a string constant.

So, the input argument must resolve to a constant string. It can be any arbitrary expression as soon as it folds into a string literal. For example, $concat: ["a", "b"] is a valid argument, as it can be folded into "ab" during the query optimization phase. While $concat: ["$a", "a"] can only be evaluated in runtime, since it contains a field path expression "$a" to extract field "a" from the input document. Runtime arguments are not supported by the $getField expression as the name of the field we're accessing should be known to the optimizer at compile time.

chris.kelly@mongodb.com With regards to this note about the $literal expression. It pertains to a scenario when you need to access a field in a document which starts with the $ symbol, as in $getField: "$a". The parser will treat "$a" as a field path expression and fail with an error like in the description to this ticket. A correct way to extract the field $a would be: $getField: {$literal: "$a"}.

I'm going to close this ticket as "Works as designed".

Comment by Chris Kelly [ 21/Jun/22 ]

Hi Boris,

Thanks for your report. I was able to reproduce your issue on MongoDB 5.0.9 and am inclined to agree that this shouldn't have an error. Specifically, there seems to be a note about something similar already:

If field begins with a dollar sign ($), place the field name inside of a $literal expression to return its value.

I tried using $literal in $getField as well to see if we could get around it that way, but I'm still having the same issue you reported.

I'll go ahead and forward this to the Query Execution team for further investigation. 

Christopher

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