使用upsert更新,但仅在db中的文档的日期字段小于更新的文档时才更新

时间:2016-12-30 00:05:43

标签: mongodb mongodb-query

我在尝试为此提出逻辑时遇到了一些问题。所以,我想做的是:

  • 批量更新一堆帖子到我的远程MongoDB实例但是
  • 如果更新,则仅在远程集合中的lastModified字段小于我要更新/插入的同一文档中的lastModified字段时更新

基本上,我想更新自上次更新文档后修改过的文档列表。 我可以想到两种蛮力的方法来做到这一点......

首先,查询我的整个集合,尝试手动删除和替换符合条件的文档,添加新文档,然后在删除远程中的所有内容后将所有内容重新插入远程集合​​。

其次,查询每个项目,然后决定,如果遥控器中有一个项目,我是否要更新或不更新。在处理远程集合时,这似乎非常有用。

如果相关,我正在使用mondodb npm包进行数据库操作的NodeJS环境。

1 个答案:

答案 0 :(得分:0)

您可以使用 bulkWrite API根据您指定的逻辑执行更新,因为它可以更好地处理此问题。

例如,以下代码段显示了如何解决此问题,假设您已经拥有需要使用以下内容更新远程集合的Web服务的数据:

mongodb.connect(mongo_url, function(err, db) {
    if(err) console.log(err);
    else {
        var mongo_remote_collection = db.collection("remote_collection_name");

        /* data is from http call to an external service or ideally
           place this within the service callback
        */
        mongoUpsert(mongo_remote_collection, data, function() {
            db.close();
        })
    }
})

function mongoUpsert(collection, data_array, cb) {      
    var ops = data_array.map(function(data) {
        return {
            "updateOne": {
                "filter": { 
                    "_id": data._id, // or any other filtering mechanism to identify a doc
                    "lastModified": { "$lt": data.lastModified }
                },
                "update": { "$set": data },
                "upsert": true
            }
        };
    });

    collection.bulkWrite(ops, function(err, r) {
        // do something with result
    });

    return cb(false);
}

如果来自外部服务的数据量巨大,那么考虑将批量写入服务器的500次发送给服务器,这样可以提高性能,因为您不是每次请求都向服务器发送一次请求。

对于批量操作,MongoDB每批执行default internal limit 1000次操作,因此在您对批量大小有一定控制权而不是让MongoDB强加默认值时,选择500个文档是好的,即<幅度>的大型操作1000份文件。因此,对于第一种方法中的上述情况,可以立即写入所有数组,因为它很小,但500选择适用于较大的数组。

var ops = [],
    counter = 0;

data_array.forEach(function(data) {
    ops.push({
        "updateOne": {
            "filter": { 
                "_id": data._id,
                "lastModified": { "$lt": data.lastModified }
            },
            "update": { "$set": data },
            "upsert": true
        }
    });
    counter++;

    if (counter % 500 === 0) {
        collection.bulkWrite(ops, function(err, r) {
            // do something with result
        });
        ops = [];
    }
})

if (counter % 500 != 0) {
    collection.bulkWrite(ops, function(err, r) {
        // do something with result
    }
}
相关问题