I have a document in MongoDB that looks like that:
{
"Id":"123",
"Product": "test",
"Tags":[
{
"Name": "name",
"Categories": [
{
//item
},
{
//item
}
]
},
{
"Name": "name",
"Categories": [
{
//item
},
{
//item
}
]
}
]
}
Now, I need to add a new Item
and it needs to be added to all of the categories of the Tags
element of that Product
by its Id
. For example, when I'll insert Item 3
the document should look like this:
{
"Id":"123",
"Product": "test",
"Tags":[
{
"Name": "name",
"Categories": [
{
//item 1
},
{
//item 2
},
{
//item 3
}
]
},
{
"Name": "name",
"Categories": [
{
//item 1
},
{
//item 2
},
{
//item 3
}
]
}
]
}
and same goes for removing an item, it needs to be removed from all of the categories as well. Is there a way to do that with the C# MongoDB Driver without pulling the object and "manually" updating them?
You can try something like below in 2.5 driver with 3.6 version.
Finds the document with filter
criteria and update
which includes new positional identifier to update multiple elements in array inside UpdateOne
method.
$[] updates all the Tags
arrays to include new item in all Categories
array. It acts as a placeholder for updating all elements in array.
Push
var filter = Builders<Product>.Filter.Eq("Id", "123");
var update = Builders<Product>.Update.Push("Tags.$[].Categories", "Item 3");
var result = collection.UpdateOne(filter, update);
Pull
var filter = Builders<Product>.Filter.Eq("Id", "123");
var update = Builders<Product>.Update.Pull("Tags.$[].Categories", "Item 3");
var result = collection.UpdateOne(filter, update);
Additional Information:
You can set the ArrayFilters
options in UpdateOptions
for applying query criteria on nested array to control what elements to update.
For example to update all the Categories in Tags array where each tag has Name
name.
var filter = Builders<Product>.Filter.Eq("Id", "123");
var update = Builders<Product>.Update.Push("Tags.$[t].Categories", "Item 3");
var arrayFilters = new List<ArrayFilterDefinition>{ new ArrayFilterDefinition(new BsonDocument("t.Name", "name")) };
var updateOptions = new UpdateOptions({ArrayFilters = arrayFilters});
var result = collection.UpdateOne(filter, update, updateOptions);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.