Disclaimer: I made a very simple minimal failing example here, but what I'm trying to achieve is in a more complicated context, and it's very important that the document can be modified atomically.
Let's say I have documents representing buildings. Each building has a list of floors (the "floors" array in the document).
[
{
_id: "DcGvSbWmOH46Dhu9O",
floors: [
{
index: 0
},
{
index: 1
},
{
index: 2
},
{
index: 3
},
{
index: 4,
cafeteria: true
}
]
}
]
In this example, there is a cafeteria at floor 4 (indicated by the field "cafeteria" set to true).
The cafeteria has closed so I'd like to remove it from the 4th floor.
Here is my attempt:
db.collection.update(
{ _id: "DcGvSbWmOH46Dhu9O" },
{
$unset: {
"floors.$[element].cafeteria": ""
}
},
{
arrayFilters: [
{
"element": {
"index": 4
}
}
]
}
)
When executed, no change happens, the element at index 4 still has the cafeteria. You can see this in mongoplayground: https://mongoplayground.net/p/mv8nUFhWSTY
Even trying to set "cafeteria" to false instead of just removing the key fails in the same way.
db.collection.update(
{ _id: "DcGvSbWmOH46Dhu9O" },
{
$set: {
"floors.$[element].cafeteria": false
}
},
{
arrayFilters: [
{
"element": {
"index": 4
}
}
]
}
)
No change (mongoplayground link: https://mongoplayground.net/p/LyeaHeU0CQF )
Adding a field that didn't existed before works, but removing an existing field or removing it doesn't work. What's happening?
By the way, I made a very simple minimal failing example here, but what I'm trying to achieve is in a different context, and it's very important that the document can be modified atomically (I want to avoid reading the document, computing a new version and sending it to Mongo, this would cause race conditions issues in multiple parts of my application).
{ "element.index": 4 }: mongoplayground.net/p/eXplS5p3g1d{ "element": { "index": 4}}does work when adding a NEW field using$set. Here is an example: mongoplayground.net/p/fh_o-0YimoS$positional operator like this or like this if only affecting one array element as opposed to usingarrayFiltersarrayFilters: [{ "element": { "index": 4}}]works to add a new field to an element of an array, but doesn't work when you try to remove a field or modify an existing field. When reading the documentation about arrayFilters, it seems to me that all three should work.$unsetattempt you would need to do an exact match onelement. So your updated query would look like this witharrayFiltersi.e matchindexandcafeteriaas well as any other key you have in that object.