Home > Blockchain >  Set and concat to string field with arrayFilters in MongoDB
Set and concat to string field with arrayFilters in MongoDB

Time:06-08

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

Playmongo

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"]}}]}]}}}}]}]}}}}}])
  • Related