Search code examples
c#mongodbasp.net-coremongodb-.net-driver

MongoDB C# Driver Update Document with Aggregation Pipeline


As described here from MongoDB 4.2 on it is possible to update documents with an aggregation pipeline.

It means that now it is possible to express "conditional updates based on current field values or updating one field using the value of another field(s)".

For instance:

db.members.update(
   { },
   [
      { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ], lastUpdate: "$$NOW" } },
      { $unset: [ "misc1", "misc2" ] }
   ],
   { multi: true }
)

My question is: how can I do this using MongoDB on C#?


Solution

  • IMongoCollection's UpdateMany takes UpdateDefinition<T> as second parameter and PipelineUpdateDefinition is one of the derived classes. There's no expression trees support so far but you can utilize BsonDocument class:

    IMongoCollection<BsonDocument> col = ...;
    var pipeline = new EmptyPipelineDefinition<BsonDocument>()
                        .AppendStage("{ $addFields : { " +
                                            "status : 'Modified'," +
                                            "comments: [ '$misc1', '$misc2' ]," +
                                            "lastUpdate: '$$NOW' " +
                                        "} }",
                            BsonDocumentSerializer.Instance)
                        .AppendStage("{ $project : { 'misc1':0, 'misc2':0 } }",
                        BsonDocumentSerializer.Instance);
    
    col.UpdateMany(new BsonDocument(), pipeline);
    

    which executes following command (trace from MongoDB driver):

    "updates" : [
        { 
            "q" : { }, 
            "u" : [
                { "$addFields" : { "status" : "Modified", "comments" : ["$misc1", "$misc2"], "lastUpdate" : "$$NOW" } }, 
                { "$project" : { "misc1" : 0, "misc2" : 0 } }], 
            "multi" : true }
        }
    ]