leroy
leroy

Reputation: 45

How to update all keys in MongoDB from a dictionary?

I have some object:

public class ObjA
{
    [BsonElement("_id")]
    public int ID { get; set; }
    
    [BsonElement("languages")]  
    public Dictionary<string, ObjB> languages { get; set; }
}

public class ObjB
{
    [BsonElement("translation_1")]
    public string Translation_1 { get; set; }
    
    [BsonElement("translation_2")]
    public string Translation_2 { get; set; }
    
    [BsonElement("translation_3")]
    public string Translation_3 { get; set; }
}

There are situations where I need to update Translation_1 property of ObjB for every key in languages property of ObjA object.

Value of key of languages dictionary is not the same for all ObjA.

So, query should update all Translation_1 properties regardless of the key

Update: So far I have not made any significant progress:

UpdateDefinition<ObjA> update = Builders<ObjA>.Update.Set("languages.-key-.translation_1", newValue);
var result = await Collection.UpdateManyAsync(x => x.Id == someID, update);

Upvotes: 0

Views: 414

Answers (1)

prasad_
prasad_

Reputation: 14287

There are situations where I need to update Translation_1 property of ObjB for every key in languages property of ObjA object.

Here is the Update with Aggregation Pipeline code, the first one is the mongo shell version and the second the C# version. The update modifies the value of the property translation_1 of ObjB, for all keys of the languages dictionary property of ObjA.

var NEW_VALUE = "some new value"
var someId = "some id value"

db.test.updateOne(
  { _id: someId },
  [
    { 
        $set: { 
            languages: {
                $map: {
                     input: { $objectToArray: "$languages" }, 
                     as: "ele",
                     in: {
                         $mergeObjects: [ 
                             "$$ele", 
                             { "v": { 
                                  "translation_1": NEW_VALUE, 
                                  "translation_2": "$$ele.v.translation_2",
                                  "translation_3": "$$ele.v.translation_3" 
                        } }  ]
                     }
                }
            } 
    }},
    { 
        $set: { 
            languages: {
                $arrayToObject: "$languages" 
            }
    }},
  ]
)

var pipeline = new BsonDocumentStagePipelineDefinition<ObjA, ObjA>(
                         new[] { 
                             new BsonDocument("$set", 
                                 new BsonDocument("languages", 
                                     new BsonDocument("$map", 
                                          new BsonDocument {
                                              { "input", new BsonDocument("$objectToArray", "$languages") }, 
                                              { "as", "ele" }, 
                                              { "in", 
                                                     new BsonDocument("$mergeObjects", 
                                                         new BsonArray {
                                                             "$$ele",
                                                                  new BsonDocument("v", 
                                                                      new BsonDocument {
                                                                          { "translation_1", NEW_VALUE },
                                                                          { "translation_2", "$$ele.v.translation_2" },
                                                                          { "translation_3", "$$ele.v.translation_3" }
                                                                  })
                                              }) }
                                          }
                             ))),
                             new BsonDocument("$set", 
                                 new BsonDocument("languages", 
                                     new BsonDocument("$arrayToObject", "$languages")
                             ))
                         } 
);

System.Linq.Expressions.Expression<Func<ObjA, bool>> filter = x => x.id == someId;
var update = new PipelineUpdateDefinition<ObjA>(pipeline);
var result =  collection.UpdateOne<ObjA>(filter, update);

Upvotes: 1

Related Questions