I would like to know whether it is possible to implement the following problem within a single call of findOneAndUpdate()
method.
Let's consider this collection entry:
[
{
"key": 1,
"logs": [
{
"app_logs": [
{
"stdout": "app_stdout_1",
"stderr": "app_stderr_1"
}
],
"syslog": "syslog_val1"
},
{
"app_logs": [
{
"stdout": "app_stdout_2",
"stderr": "app_stderr_2"
}
],
"syslog": "syslog_val2"
}
]
},
]
I need to push an additional element into app_logs
array but only within the last entry of logs
array. Currently to bypass this issue, I fetch the document as it is, execute such push in the application and then use findOneAndReplace()
method. While this works I would like it to be implemented within a single MongoDB call. I have tried various approaches like pipeline aggregations, update array filters etc. but could not get any of them to work. Also tried to find the solution online, and read the docs but still can't find any similar problem that was successfully solved.
The most common similar problem people tend to hit is updating specific element in a nested array under conditions that can be solved by using a positional operator with something like:
findOneAndUpdate({
"key": 1,
"logs.syslog": "syslog_val1"
},
{
"$push": {
"logs.$.app_logs": {
"stdout": "app_stdout_new",
"stderr": "app_stderr_new"
}
}
})
In my case, I want to execute such push not for the specific element of the logs
array but only for the last one. Since I already spent a lot of time with this problem it leads me to the question of whether it is even possible to implement or whether there are any limitations with the current MongoDB version which would make such implementation impossible.
Thanks for any help.
For your scenario, via update query with Aggregation Pipeline to achieve it.
$set
- Get the last element oflogs
aslastLog
.$set
2.1
$concatArrays
- Merge arrays with all the elements oflogs
(except the last document) and the result of 2.2.2.2
$mergeObjects
- Merge objects withlastLog
and the result of 2.3 aimed to override theapp_logs
field.2.3
$concatArrays
- Merge arrays withlastLog.app_logs
and new document (as array).$unset
- RemovelastLog
field.Sample Mongo Playground