I want to remove one field from every document using MongoDB driver for C#.
I have documents like this:
{
"_id": ObjectId("554e05dfc90d3d4dfcaa2aea"),
"username": "abc",
"someArray": [
{
"_id": ObjectId("554e0625a51586362c33c6df"),
"IsReadOnly": false
},
{
"_id": ObjectId("554e0625a51586362c33c6df"),
"IsReadOnly": true
}
]
}
I want to remove the field "IsReadOnly" from "someArray", regardless of whether the value is true or false.
In MongoDB I can reach that with the following script:
db.getCollection('Collection').find({}).forEach( function(doc) {
var arr = doc.someArray;
var length = arr.length;
for (var i = 0; i < length; i++) {
delete arr[i]["IsReadOnly"];
}
db.getCollection('Collection').save(doc);
});
In C# I tried the following:
var update= Update.Pull("someArray",BsonValue.Create("IsReadOnly"));
// or: var update = Update.Unset("someArray.$[].IsReadOnly");
myDb.Collection.Update(null, update, UpdateFlags.Multi);
But the "IsReadOnly" wasn't deleted. How can I delete this field from every array and every document?
In the Mongo Query Language the easiest way you can express this update is using the $[]
(Positional All) operator. It looks something like this:
db.col.update({},{$unset:{"someArray.$[].IsReadOnly":1}},{multi:true})
However, this operator has not been explicitly implemented in the strongly typed Builders
available in the C# Driver.
Since this operator is missing you have to build the update "by hand". Here's a quick sample.
var mongo = new MongoClient();
var db = mongo.GetDatabase("test");
var col = db.GetCollection<BsonDocument>("col");
await col.UpdateManyAsync(new BsonDocument(), Builders<BsonDocument>.Update.Unset("someArray.$[].IsReadOnly"));
There are some potential pitfalls here with field naming if you have some custom serialization settings (such as lower camel cased field names), so be sure to test things.
It is worth noting that this answer is contingent upon you running a version of MongoDB that is 3.6 or newer. If you are running an older version, this method will not work as the $[]
operator does not exist in earlier versions.