[SERVER-63733] Allow individual updates to accept parameters for non-pipeline updates Created: 16/Feb/22  Updated: 17/Nov/23

Status: Backlog
Project: Core Server
Component/s: Query Language
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Katya Kamenieva Assignee: Backlog - Query Optimization
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
is depended on by DRIVERS-2183 Support 'let' option in BulkWriteOptions Implementing
Related
is related to SERVER-63704 Allow for each individual delete to a... Backlog
Assigned Teams:
Query Optimization
Participants:

 Description   

Currently in the update command, if you specify 'c' in the individual element of the 'updates' array, and the update description 'u' is not a pipeline-update, you'll get an error "code: 51198, errmsg: 'Constant values may only be specified for pipeline updates'".

db.people.insertOne({name: "Andy"})
db.runCommand(
   {
     update: "people",
     updates: [
       { 
        q: { $expr: { $eq: [ "$name", "$$nameVar" ] } }, 
        u: {  $inc: { score: 1 } }, 
        multi: true,
        c: {nameVar: "Andy"}
        }
     ]
   }
)

This prevents using parameters defined in 'c' in the 'q' filter part of the update.
Also, it is not consistent with 'let' where you can set parameters on the command level, and it will not produce an error for the non-pipeline updates.

db.runCommand(
   {
     update: "people",
     updates: [
       { 
        q: { $expr: { $eq: [ "$name", "$$nameVar" ] } }, 
        u: {  $inc: { score: 1 } }, 
        multi: true
        }
     ],
     let: {nameVar: "Andy"}
   }
)



 Comments   
Comment by Jeremy Mikola [ 16/Feb/22 ]

By this ticket I wanted to enable "accessed from a query (using $expr...)" - the first update query in the description

kateryna.kamenieva: My apologies for not reading the description thoroughly. I mistakenly thought this issue was requesting the server allow c to apply to non-pipeline updates. I see now you were noting that the server raises an error simply for specifying the c option whenever u is not a pipeline, which prevents it from being used with q and $expr alone.


david.storch: I'm probably not using the correct terminology, as I'm not familiar with the internal server code, but by "aggregation context" I just meant being able to access Variables in Aggregation Expressions. AFAIK, that's what let and c are used to declare.

Pipeline-style updates implicitly support aggregation expressions, which allow references to those variables via "$$" syntax. Similarly, using $expr in a query (e.g. find or update q option) allows access to aggregation expressions, so queries can use "$$" syntax within $expr.

Comment by David Storch [ 16/Feb/22 ]

jmikola, I'm not sure what you mean by this:

as the let bindings only apply to aggregation contexts

What do you mean here by an "aggregation context"? I think let just binds a variable that is accessible to any expression in the CRUD operation. For updates, that expression may appear either in the match part or in the update part.

Comment by Katya Kamenieva [ 16/Feb/22 ]

By this ticket I wanted to enable "accessed from a query (using $expr...)" - the first update query in the description

Comment by Jeremy Mikola [ 16/Feb/22 ]

I'm not sure this is technically feasible, as the let bindings only apply to aggregation contexts. As such, they can only be accessed from a query (using $expr to access that context) or a pipeline-style update, which implicitly has access to that context.

This just came up in DRIVERS-2210 if you'd like some more context (no pun intended).


Edit: this comment was a misunderstanding on my part. Please disregard.

Generated at Thu Feb 08 05:58:31 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.