[CSHARP-3677] How to update document field with another field Created: 19/May/21  Updated: 18/Jan/24

Status: Backlog
Project: C# Driver
Component/s: Builders
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Unknown
Reporter: yongxing Liang Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently I can use UpdateBuilder to update document,but  how can I tell it use value of field B o update field A?

 

// code placeholder
 
var builder = Builders<T>.Update; 
//Seems builder.Set("A","$B");
// will update value of field 'A' to be '$B', but not the value of field B

 



 Comments   
Comment by yongxing Liang [ 04/Jun/21 ]

Understood, thanks, @james.  BTW if Builder.Set somehow allow reference field that would be great.

Comment by James Kovacs [ 31/May/21 ]

Hi, fomanlion@gmail.com,

Thank you reaching out to us regarding updating a field using another field in the same document.

The UpdateDefinitionBuilder<T>.Set method takes a field definition (in your case "A") and a value (in your case "$B"). Notably that value cannot be computed from another field. It has to be a static value.

var filter = Builders<BsonDocument>.Filter.Empty;
var builder = Builders<BsonDocument>.Update;
var update = builder.Set("A", "$B");
coll.UpdateMany(filter, update);

This generates the following update operation, which is sent to MongoDB:

db.coll.updateMany({}, { $set: { A: "$B" } })

Note that the second argument is a simple $set operation, which doesn't allow field references or other aggregation pipeline features. This is why the field A is set to the literal string $B.

In order to use aggregation features in your updates, you must supply an aggregation pipeline as the second argument:

var filter = Builders<BsonDocument>.Filter.Empty;
var pipeline = PipelineDefinition<BsonDocument, BsonDocument>.Create("{$set: {A: '$B'}}");
coll.UpdateMany(filter, pipeline);

This sends the very similar-looking, but fundamentally different operation to MongoDB:

db.coll.updateMany({}, [ { $set: { A: "$B" } } ])

Note the square brackets around the second argument indicating that it is an array of pipeline stages. Now MongoDB knows that you are using field references and will set field A to the value of field B.

At the moment the .NET/C# driver does not provide any strongly-typed builders to create a pipeline update definition with the $set operation. You must specify the operation using JSON strings or BsonDocument.

Please let us know if you have any additional questions.

Sincerely,
James

Generated at Wed Feb 07 21:45:58 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.