My MongoDB document looks like this.
{
_id: '556ebf103a8b4c3d067bb6466df7c0651c53a1ff79fa348edff656586c24ad0c',
Log: [
{
ScriptName: 'UpdateScript',
ScriptLogs: [
{
ID: 'f5bd1fefb2a5c4712ea1d35eb5bd309074984c5932db3723cc29f8d92258a3fa',
StdOut: 'Hello'
}
]
}
]}
I have the MongoDb Query
db.getCollection("ServerEntitys").update(
{_id: '556ebf103a8b4c3d067bb6466df7c0651c53a1ff79fa348edff656586c24ad0c'},
{
$set: {
'Log.$[i].ScriptLogs.$[j].StdOut': { "$concat": ["$Log.$[i].ScriptLogs.$[j].StdOut", "World"]}
}
},
{ arrayFilters: [ { "i.ScriptName": "UpdateScript" } , { "j.ID": 'f5bd1fefb2a5c4712ea1d35eb5bd309074984c5932db3723cc29f8d92258a3fa'} ] }
)
After running the query I get
StdOut: {
$concat: [
'$Log.$[i].ScriptLogs.$[j].StdOut',
'World'
]
},
instead of
StdOut: 'HelloWorld'
Can someone tell me why mongoDB uses $concat as value and not as a $concat instruction
CodePudding user response:
When you are using normal update, you should use ONLY update operators
After MongoDB 4.2, we can also update using a pipeline update, using ONLY aggregate operators (no update ones, no arrayfilters etc)
We dont have an update operator that concat strings, so looks like you need pipeline update like the bellow.
Query
- nested
$map
- outer to match the
updateScript
- inner to match the
ID
- in both cases if no match is found we keep the old array member
coll.updateMany({},
[{"$set":
{"Log":
{"$map":
{"input": "$Log",
"as": "outer",
"in":
{"$cond":
[{"$ne": ["$$outer.ScriptName", "UpdateScript"]}, "$$outer",
{"$mergeObjects":
["$$outer",
{"ScriptLogs":
{"$map":
{"input": "$$outer.ScriptLogs",
"as": "inner",
"in":
{"$cond":
[{"$ne": ["$$inner.ID", "2"]}, "$$inner",
{"$mergeObjects":
["$$inner",
{"StdOut":
{"$concat":
["$$inner.StdOut"," World"]}}]}]}}}}]}]}}}}}])