【问题标题】:Updating an object property in a nested collection with another property of this object in MongoDB with c# driver使用 c# 驱动程序在 MongoDB 中使用该对象的另一个属性更新嵌套集合中的对象属性
【发布时间】:2020-07-15 07:07:18
【问题描述】:

我需要更新 nested 集合中的属性。所有示例都描述了设置具体值,而不是来自另一个字段的值。

MongoDB 版本:4.2

C#驱动版本:2.10.4

产品示例:

    {
     _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));

但是我如何将Variants.Price 更新为Variants.OriginalPrice?尝试

var pipeline = PipelineDefinition<Product, Product>.Create("{'$set': {'Price': '$OriginalPrice', 'Variants.$[].Price': '$Variants.$[].OriginalPrice'}}");
productCollection.UpdateMany(FilterDefinition<Product>.Empty, Builders<Product>.Update.Pipeline(pipeline));

但是发生了错误。

更新 1:变体包含其他属性。

@Mickl 的answer 是解决方案,但是

覆盖整个嵌套集合是最佳方式吗?

【问题讨论】:

    标签: c# mongodb aggregation-framework mongodb-.net-driver


    【解决方案1】:

    更新表达式的右侧需要是 MongoDB 聚合表达式1,目前您使用的是常规“更新”语法。基于docs

    指定要添加的每个字段的名称,并将其值设置为聚合表达式。有关表达式的更多信息,请参阅表达式

    $map 操作符可以用来实现你想要的:

    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));
    

    【讨论】:

    • 谢谢@mickl!地图的好方法。如果我在变体对象中有许多其他属性,是否有更好的解决方案而不重写所有嵌套的 Variants 集合?如果变体对象在其他文档中包含不同的属性怎么办?
    • @EvgenyIvanov 当然,你可以使用$mergeObjects。查看我修改后的答案
    • 谢谢,刚刚找到这个解决方案并进行了有问题的更新 :) 覆盖整个嵌套集合是最佳方式吗?
    • @EvgenyIvanov 我相信是这样
    猜你喜欢
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多