问题
I need to update property in nested collection. All examples describes about setting concrete value, but not about value from another field.
MongoDB version: 4.2
C# driver version: 2.10.4
Product example:
{
_id: "1",
Title: "Some title",
Price: 20,
OriginalPrice: 10,
... other props ...
Variants:
[
{
Price: 21,
OriginalPrice: 11
... other props ...
},
{
Price: 22,
OriginalPrice: 13
... other props ...
},
]
}
I know how to update Price
var pipeline = PipelineDefinition<Product, Product>.Create("{'$set': {'Price': '$OriginalPrice'}}");
productCollection.UpdateMany(FilterDefinition<Product>.Empty, Builders<Product>.Update.Pipeline(pipeline));
But how i can update Variants.Price
as Variants.OriginalPrice
? Trying
var pipeline = PipelineDefinition<Product, Product>.Create("{'$set': {'Price': '$OriginalPrice', 'Variants.$[].Price': '$Variants.$[].OriginalPrice'}}");
productCollection.UpdateMany(FilterDefinition<Product>.Empty, Builders<Product>.Update.Pipeline(pipeline));
but an error occured.
Upd 1: Variant contains other properties.
@Mickl's answer is the solution, but
Is overwriting the entire nested collection the most optimal way?
回答1:
The right handside of your update expression needs to be a MongoDB aggregate expression1 and currently you're using the regular "update" syntax. Based on the docs:
Specify the name of each field to add and set its value to an aggregation expression. For more information on expressions, see Expressions
The $map operator can be used to achieve what you want:
var set = @"{
$set:
{
Variants:
{
$map:
{
input: '$Variants',
in: { $mergeObjects: [ '$$this', { Price: '$$this.OriginalPrice' } ] }
}
}
}
}";
var pipeline = PipelineDefinition<Product, Product>.Create(set);
var res = productCollection.UpdateMany(FilterDefinition<Product>.Empty, Builders<Product>.Update.Pipeline(pipeline));
来源:https://stackoverflow.com/questions/62909340/updating-an-object-property-in-a-nested-collection-with-another-property-of-this