JonnyJon44
JonnyJon44

Reputation: 69

MongoDB .NET Driver update Cannot use the part ... to traverse the element

I'm trying to rename a field but I end up getting an error. What could I be missing?

A write operation resulted in an error. cannot use the part (Orders of Orders.Number) to traverse the element ({Orders: [ { CustomFields: { Пара паков: { FieldId: ObjectId('61e670f9c0fe1106a51a2e23'), Type: "Text", ValueBson: "8989" }, Weight: { FieldId: ObjectId('6149d5de44175b8324482915'), Type: "Number", ValueBson: 2222 } }, _id: ObjectId('61e6751027c21629e070091b'), Number: "21312" } ]})

var orderFilter = Builders<VisitTask>.Filter.Empty;
UpdateDefinition<VisitTask> update = Builders<VisitTask>.Update.Rename($"Orders.Number", $"Orders.TestNumber");
Collection.UpdateMany(orderFilter, update, new UpdateOptions { IsUpsert = true });

Document

{
    "_id" : ObjectId("61e674fa27c21629e070091a"),
    "LastUpdateDate" : ISODate("2022-01-18T08:07:52.008Z"),
    "Orders" : [ 
        {
            "CustomFields" : {
                "Пара паков" : {
                    "FieldId" : ObjectId("61e670f9c0fe1106a51a2e23"),
                    "Type" : "Text",
                    "ValueBson" : "8989"
                }
            },
            "_id" : ObjectId("61e6751027c21629e070091b"),
            "Number" : "21312"
        }
    ],
}

Upvotes: 0

Views: 283

Answers (1)

Yong Shun
Yong Shun

Reputation: 51160

$rename operator is not able to work in updating the field name in a nested array.

Instead, you need $set the existing Number value(s) to new field TestNumber with $map. Then $unset to remove Orders.TestNumber field.

Note: The previous answer will result in incorrect output. Need to use $map for updating the objects in array.

db.collection.update({},
[
  {
    $set: {
      Orders: {
        $map: {
          input: "$Orders",
          in: {
            $mergeObjects: [
              {
                "Number-test": "$$this.Number"
              },
              "$$this"
            ]
          }
        }
      }
    }
  },
  {
    $unset: "Orders.Number"
  }
],
{
  multi: true
})

Sample Mongo Playground


[For MongoDB .Net Driver version 2.13]

To C#, you need to use UpdateDefinitionBuilder<TDocument>.Pipeline Method as below:

Solution 1

UpdateDefinition<VisitTask> update = Builders<VisitTask>.Update.Pipeline(
    new PipelineStagePipelineDefinition<VisitTask, VisitTask>(
        new PipelineStageDefinition<VisitTask, VisitTask>[]
        {
            new BsonDocument("$set", 
                new BsonDocument("Orders", 
                    new BsonDocument("$map", 
                        new BsonDocument
                        {
                            { "input", "$Orders" }, 
                            { "in", 
                                new BsonDocument("$mergeObjects", 
                                    new BsonArray
                                    {
                                        new BsonDocument("Number-test", "$$this.Number"),
                                        "$$this"
                                    }) 
                            }
                        }))),
            new BsonDocument("$unset", "Orders.Number")
        }));

Solution 2

UpdateDefinition<VisitTask> update = Builders<VisitTask>.Update.Pipeline(
    new BsonDocument[]
    {
        new BsonDocument("$set", 
            new BsonDocument("Orders", 
                new BsonDocument("$map", 
                    new BsonDocument
                    {
                        { "input", "$Orders" }, 
                        { "in", 
                            new BsonDocument("$mergeObjects", 
                                new BsonArray
                                {
                                    new BsonDocument("Number-test", "$$this.Number"),
                                    "$$this"
                                }) 
                        }
                    }))),
        new BsonDocument("$unset", "Orders.Number")
    }
);

Upvotes: 1

Related Questions