使用c#driver在MongoDB中使用此对象的另一个属性更新嵌套集合中的对象属性
我需要更新嵌套的集合中的属性。所有示例都描述了如何设置具体值,但没有描述来自另一个字段的值 MongoDB版本:4.2 C#驱动程序版本:2.10.4 产品示例:使用c#driver在MongoDB中使用此对象的另一个属性更新嵌套集合中的对象属性,c#,mongodb,aggregation-framework,mongodb-.net-driver,C#,Mongodb,Aggregation Framework,Mongodb .net Driver,我需要更新嵌套的集合中的属性。所有示例都描述了如何设置具体值,但没有描述来自另一个字段的值 MongoDB版本:4.2 C#驱动程序版本:2.10.4 产品示例: { _id: "1", Title: "Some title", Price: 20, OriginalPrice: 10, ... other props ... Variants: [ {
{
_id: "1",
Title: "Some title",
Price: 20,
OriginalPrice: 10,
... other props ...
Variants:
[
{
Price: 21,
OriginalPrice: 11
... other props ...
},
{
Price: 22,
OriginalPrice: 13
... other props ...
},
]
}
我知道如何更新Price
var pipeline = PipelineDefinition<Product, Product>.Create("{'$set': {'Price': '$OriginalPrice'}}");
productCollection.UpdateMany(FilterDefinition<Product>.Empty, Builders<Product>.Update.Pipeline(pipeline));
但是发生了一个错误
Upd 1:变量包含其他属性
@米克尔是解决办法,但是
覆盖整个嵌套集合是否是最佳方式?更新表达式的右侧需要是MongoDB聚合表达式,并且当前使用的是常规的“更新”语法。根据: 指定要添加的每个字段的名称,并将其值设置为聚合表达式。有关表达式的详细信息,请参见表达式 操作员可用于实现您想要的:
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));
var set=@”{
$set:
{
变体:
{
$map:
{
输入:“$Variants”,
在:{$mergeObjects:['$$this',{Price:'$$this.OriginalPrice'}]}
}
}
}
}";
var pipeline=PipelineDefinition.Create(set);
var res=productCollection.UpdateMany(FilterDefinition.Empty,Builders.Update.Pipeline(Pipeline));
谢谢@mickl!很好的地图处理方法。如果variant对象中有许多其他属性,是否有更好的解决方案,而不重写所有嵌套的variant集合?如果variant对象在其他文档中包含不同的属性怎么办?@EvgenyIvanov当然,您可以使用$mergeObjects
。查看我修改过的答案谢谢,刚刚找到了这个解决方案和有问题的更新:)覆盖整个嵌套集合是最理想的方式吗?@EvgenyIvanov我相信是的
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));