[SERVER-11345] Allow update to compute expressions using referenced fields like Aggregation Framework's $project Created: 24/Oct/13  Updated: 06/Dec/22  Resolved: 29/Jun/19

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

Type: Improvement Priority: Major - P3
Reporter: Avishay Lavie Assignee: Backlog - Query Team (Inactive)
Resolution: Done Votes: 29
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SERVER-3089 Ability to make use of a subdocument'... Closed
is duplicated by SERVER-15918 Unable to create field with update wh... Closed
Related
related to SERVER-458 JavaScript $function in update Closed
related to SERVER-1765 self referential updates? WAS: allow ... Closed
related to SERVER-22893 Update should provide more than $inc ... Closed
related to SERVER-22940 Add support of more math operations o... Closed
is related to SERVER-20510 Add stored procedure functionality Closed
is related to SERVER-9366 Expose projection (aggregation) opera... Closed
Assigned Teams:
Query
Participants:
Case:

 Description   

AF's $project allows us to compose arbitrary expressions using referenced fields from the document and primitive arithmetic operators.

In contrast, update() only allows us to $inc a field or $set it, but not e.g. to multiply it by a constant (I see this was added in 2.6) or by another field.

As an example, suppose I want to update a document containing the average rating of a product and the number of ratings it got.

I want to be able to add a new rating in an atomic update by writing something like:

db.products.update({ _id: 7 }, {
  $mul: { averageRating: '$ratingCount' },
  $add: { averageRating: 5 },
  $inc: { ratingCount: 1 },
  $div: { averageRating: '$ratingCount' }
});

Alternatively I'd like to be able to run a user-provided JS function as part of the update, like the $where operator for queries, except this function can update the document.



 Comments   
Comment by Asya Kamsky [ 29/Jun/19 ]

SERVER-40381 implemented support for aggregation expressions to specify update for 4.2. 

You can see some examples here.

Comment by Avishay Lavie [ 05/Nov/13 ]

Just found out this is pretty much what is requested in one of the comments on SERVER-458.
The syntax there is also acceptable, e.g.:

db.products.update({ _id: 7}, {
  $set: { avgRating: { $divide: [
    { $mul: ['$avgRating', '$ratingCount'] }, 
    { $add: ['$ratingCount', 1] }
  ] } },
  $inc: { ratingCount: 1 }
});

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