MongoDB concatenate strings from two fields into a third field
Asked Answered
S

8

30

How do I concatenate values from two string fields and put it into a third one?

I've tried this:

db.collection.update(
  { "_id": { $exists: true } },
  { $set: { column_2: { $add: ['$column_4', '$column_3'] } } },
  false, true
)

which doesn't seem to work though, and throws not ok for storage.

I've also tried this:

db.collection.update(
  { "_id": { $exists : true } },
  { $set: { column_2: { $add: ['a', 'b'] } } },
  false, true
)

but even this shows the same error not ok for storage.

I want to concatenate only on the mongo server and not in my application.

Swanhilda answered 10/10, 2012 at 13:15 Comment(4)
see <https://mcmap.net/q/500151/-mongodb-concatenate-results>?Malfunction
forEach is inefficient, multiple update is what I'm looking for. Also it doesn't explain, how to update the value of another field with the concatenated string, this is what I'm looking for col3 = col1 + col2 "+" implying concatenationSwanhilda
Mongodb does not, atm, allow the relfection of it's own document fields within the query without using JS functions. I would strongly advise not using the JS functions since they have been proven to make a query 10x slower and also have other problems. You will need to find some creative way of solving thisAlcantar
As to normal string concatenation you dont need a $add op since it is isn't like SQL, instead you can just do column_2:'a'+'b'Alcantar
T
10

Unfortunately, MongoDB currently does not allow you to reference the existing value of any field when performing an update(). There is an existing Jira ticket to add this functionality: see SERVER-1765 for details.

At present, you must do an initial query in order to determine the existing values, and do the string manipulation in the client. I wish I had a better answer for you.

Tutelary answered 10/10, 2012 at 21:48 Comment(1)
FYI (7 years later) MongoDB has multiple ways to accomplish this without client-side code. This was the best answer in 2012, but William Z's wish for a better answer has been granted. :)Umbrage
G
33

You can use aggregation operators $project and $concat:

db.collection.aggregate([
  { $project: { newfield: { $concat: [ "$field1", " - ", "$field2" ] } } }
])
Genetic answered 21/1, 2016 at 21:24 Comment(3)
The correct answer would include $out as the last pipeline stage, to output in the same collection (or a new one), since OP wants to update the collectionSalesclerk
MongoDB 4.2 now has a $merge pipeline stage which has some advantages over $out, depending on your performance, concurrency and consistency requirements.Umbrage
What would the above aggregation look like with a step that updates the existing document with the new concatenated field?Alary
T
10

Unfortunately, MongoDB currently does not allow you to reference the existing value of any field when performing an update(). There is an existing Jira ticket to add this functionality: see SERVER-1765 for details.

At present, you must do an initial query in order to determine the existing values, and do the string manipulation in the client. I wish I had a better answer for you.

Tutelary answered 10/10, 2012 at 21:48 Comment(1)
FYI (7 years later) MongoDB has multiple ways to accomplish this without client-side code. This was the best answer in 2012, but William Z's wish for a better answer has been granted. :)Umbrage
E
7

You could use $set like this in 4.2 which supports aggregation pipeline in update.

db.collection.update(
   {"_id" :{"$exists":true}},
   [{"$set":{"column_2":{"$concat":["$column_4","$column_3"]}}}]
)
Ekaterinoslav answered 4/10, 2019 at 1:10 Comment(0)
U
2

Building on the answer from @rebe100x, as suggested by @Jamby ...

You can use $project, $concat and $out (or $merge) in an aggregation pipeline. https://docs.mongodb.org/v3.0/reference/operator/aggregation/project/ https://docs.mongodb.org/manual/reference/operator/aggregation/concat/ https://docs.mongodb.com/manual/reference/operator/aggregation/out/

For example:

    db.collection.aggregate(
       [
          { $project: { newfield: { $concat: [ "$field1", " - ", "$field2" ] } } },
          { $out: "collection" }
       ]
    )

With MongoDB 4.2 . . .

MongoDB 4.2 adds the $merge pipeline stage which offers selective replacement of documents within the collection, while $out would replace the entire collection. You also have the option of merging instead of replacing the target document.

    db.collection.aggregate(
       [
          { $project: { newfield: { $concat: [ "$field1", " - ", "$field2" ] } } },
          { $merge: { into: "collection", on: "_id", whenMatched: "merge", whenNotMatched: "discard" }
       ]
    )

You should consider the trade-offs between performance, concurrency and consistency, when choosing between $merge and $out, since $out will atomically perform the collection replacement via a temporary collection and renaming.

https://docs.mongodb.com/manual/reference/operator/aggregation/merge/ https://docs.mongodb.com/manual/reference/operator/aggregation/merge/#merge-out-comparison

Umbrage answered 10/10, 2019 at 21:35 Comment(0)
N
2

**

in my case this $concat worked for me ...

**

db.collection.update( { "_id" : {"$exists":true} }, 
   [ { 
       "$set" : { 
                 "column_2" :  { "$concat" : ["$column_4","$column_3"] }
                }
      }
   ]
Numerate answered 29/1, 2020 at 4:48 Comment(0)
F
1

You can also follow the below.

db.collectionName.find({}).forEach(function(row) { 
    row.newField = row.field1 + "-" + row.field2
    db.collectionName.save(row);
});
Freewill answered 18/9, 2017 at 3:13 Comment(0)
O
1

let suppose that you have a collection name is "myData" where you have data like this

{
"_id":"xvradt5gtg",
"first_name":"nizam",
"last_name":"khan",
"address":"H-148, Near Hero Show Room, Shahjahanpur",
}

and you want concatenate fields (first_name+ last_name +address) and save it into "address" field like this

{
"_id":"xvradt5gtg",
"first_name":"nizam",
"last_name":"khan",
"address":"nizam khan,H-148, Near Hero Show Room, Shahjahanpur",
}

now write query will be

{
var x=db.myData.find({_id:"xvradt5gtg"});
x.forEach(function(d)
    { 
        var first_name=d.first_name;
        var last_name=d.last_name;
        var _add=d.address;  
        var fullAddress=first_name+","+last_name+","+_add; 
        //you can print also
        print(fullAddress); 
        //update 
        db.myData.update({_id:d._id},{$set:{address:fullAddress}});
    })
}
Oversell answered 28/2, 2018 at 10:47 Comment(0)
E
0

Find and Update Each Using For Loop

  1. Try This:

    db.getCollection('users').find({ }).forEach( function(user) {
        user.full_name = user.first_name + " " + user.last_name;
        db.getCollection('users').save(user);
    });
    
  2. Or Try This:

    db.getCollection('users').find({ }).forEach( function(user) {
        db.getCollection('users').update(
            { _id: user._id },
            { $set: { "full_name": user.first_name + " " + user.last_name } }
        )
    });
    
Epidaurus answered 22/4, 2022 at 14:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.