Upsert Multiple Records with MongoDb

后端 未结 3 2105
广开言路
广开言路 2021-01-05 13:25

I\'m trying to get MongoDB to upsert multiple records with the following query, ultimately using MongoMapper and the Mongo ruby driver.

db.foo.update({event_         


        
3条回答
  •  一个人的身影
    2021-01-05 14:08

    I found a way to do this using the eval operator for server-side code execution. Here is the code snippit:

    def batchpush(body, item_opts = {})
        @batch << {
            :body => body,
            :duplicate_key => item_opts[:duplicate_key] || Mongo::Dequeue.generate_duplicate_key(body),
            :priority => item_opts[:priority] || @config[:default_priority]
        }
    end
    
    def batchprocess()
        js = %Q|
            function(batch) {
                var nowutc = new Date();
                var ret = [];
                for(i in batch){
                    e = batch[i];
                    //ret.push(e);
                    var query = {
                        'duplicate_key': e.duplicate_key,
                        'complete': false,
                        'locked_at': null
                    };
                    var object = {
                        '$set': {
                            'body': e.body,
                            'inserted_at': nowutc,
                            'complete': false,
                            'locked_till': null,
                            'completed_at': null,
                            'priority': e.priority,
                            'duplicate_key': e.duplicate_key,
                            'completecount': 0
                        },
                        '$inc': {'count': 1}
                    };
    
                    db.#{collection.name}.update(query, object, true);
                }
                return ret;
            }
        |
        cmd = BSON::OrderedHash.new
        cmd['$eval'] = js
        cmd['args'] = [@batch]
        cmd['nolock'] = true
        result = collection.db.command(cmd)
        @batch.clear
        #pp result
    end
    

    Multiple items are added with batchpush(), and then batchprocess() is called. The data is sent as an array, and the commands are all executed. This code is used in the MongoDequeue GEM, in this file.

    Only one request is made, and all the upserts happen server-side.

提交回复
热议问题