Search code examples
mongodbconcatenation

Mongodb: concat to existing document


I have my collection like this:

{
"_id" : "ID1234",
"read_object" : "sss-ssss",
"expireAt" : ISODate("2020-04-30T22:00:00.000Z")
}

In case he encounters the same ID, I would like to update the read_object field, otherwise create a new document. I tried to do it like this:

db.collection.update(
{ _id: "ID1234" },
{
  $set: { read_object: { $concat: ["$read_object", "test"] } }, 
},
{ upsert: true }
)

but I get an error every time:

The dollar ($) prefixed field '$concat' in 'read_object.$concat' is not valid for storage.

If I add square brackets before $set, like this:

db.collection.update(
{ _id: "1b1b871493-14a0-4d21-bd74-086442df953c-2020-02" },
[{
  $set: { read_object: { $concat: ["$read_object", "test"] } }, 
}],
{ upsert: true }
)

I get this error:

The dollar ($) prefixed field '$concat' in 'read_object.$concat' is not valid for storage.

Where do I have a mistake?


Solution

  • $concat is an aggregation operator, meaning you can't use it while using the basic update syntax as you can only use update operators on it.

    With that said Mongo version 4.2 introduces pipeline updates, which is basically what you're trying to do with the square brackets.

    Assuming you are using Mongo version 4.2 heres a working example:

    db.test1.update({_id: "ID1234"}, [
        {$set: {"read_object": {$concat: [{$ifNull: ["$read_object", ""]}, "test"]}}}
    ], {upsert: true});
    

    Basically we just need to "replace" read_object if document does not exist as it is undefined in that case.

    If you are using Mongo version that's smaller than 4.2 then unfortunately there is no way to do what you want in one operation, you'll have to first read the document and then adjust accordingly.