Updating an object property in a nested collection with another property of this object in MongoDB with c# driver

只愿长相守 提交于 2021-01-28 10:00:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!