...
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.
alien commented on Wed, 22 Jun 2022 07:48:19 +0000: Done! JIRAUSER1265262 commented on Tue, 21 Jun 2022 16:34:03 +0000: 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 alien commented on Tue, 21 Jun 2022 15:59:38 +0000: 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! anton.korshunov commented on Tue, 21 Jun 2022 15:35:37 +0000: 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". JIRAUSER1265262 commented on Tue, 21 Jun 2022 04:22:01 +0000: 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