Append a string to the end of an existing field in

2019-01-19 14:54发布

问题:

I have been doing some research during the last couple of days to find an answer, but without luck. :(

I have a document with a field containing a very long string. I need to concatenate another string to the end of the string already contained in the field.

The way I do it now is that, from Java, I fetch the document, extract the string in the field, append the string to the end and finally update the document with the new string.

The problem: The string contained in the field is very long, which means that it takes time and resources to retrieve and work with this string in Java. Furthermore, this is an operation that is done several times per second.

My question: Is there a way to concatenate a string to an existing field, without having to fetch (db.<doc>.find()) the contents of the field first? In reality all I want is (field.contents += new_string).

I already made this work using Javascript and eval, but as I found out, MongoDB locks the database when it executes javascript, which makes the overall application even slower.

Thank you in advance. :)

回答1:

For example (it's append to the start, the same story ):

before

{ "_id" : ObjectId("56993251e843bb7e0447829d"), "name" : "London City", "city" : "London" }

db.airports
   .find( { $text: { $search: "City" } })
   .forEach(
       function(e, i){ 
           e.name='Big ' + e.name; 
           db.airports.save(e);
       }
    )

after:

{ "_id" : ObjectId("56993251e843bb7e0447829d"), "name" : "Big London City", "city" : "London" }



回答2:

Old topic but i had the same problem. Since mongo 2.4, you can use $concat from aggregation framework.

Example

Consider these documents :

{
    "_id" : ObjectId("5941003d5e785b5c0b2ac78d"),
    "title" : "cov"
}

{
    "_id" : ObjectId("594109b45e785b5c0b2ac97d"),
    "title" : "fefe"
}

Append fefe to title field :

db.getCollection('test_append_string').aggregate(
    [
        { $project: { title: { $concat: [ "$title", "fefe"] } } }
    ]
)

The result of aggregation will be :

{
    "_id" : ObjectId("5941003d5e785b5c0b2ac78d"),
    "title" : "covfefe"
}

{
    "_id" : ObjectId("594109b45e785b5c0b2ac97d"),
    "title" : "fefefefe"
}

You can then save the results with a bulk, see this answer for that.



回答3:

This would not be possible. One optimization you can do is create batches of updates. i.e. fetch 10K documents, append relevant strings to each of their keys, and then save them as single batch. Most mongodb drivers support batch operations.



回答4:

this is a sample of one document i have :

{
    "_id" : 1,
    "s" : 1,
    "ser" : 2,
    "p" : "9919871172",
    "d" : ISODate("2018-05-30T05:00:38.057Z"),
    "per" : "10"
}

to append a string to any feild you can run a forEach loop throught all documents and then update desired field:

db.getCollection('jafar').find({}).forEach(function(el){
    db.getCollection('jafar').update(
        {p:el.p},
        {$set:{p:'98'+el.p}})    
    })


回答5:

db.getCollection('<collection>').update(
    // query 
    {},

    // update 
    {
        $set: {<field>:this.<field>+"<new string>"}
    },

    // options 
    {
        "multi" : true,  // update only one document 
        "upsert" : false  // insert a new document, if no existing document match the query 
    });


标签: mongodb