使用mongoose .update查询,您可以在update参数中引用获取的记录吗?

时间:2016-08-31 23:06:50

标签: mongodb mongoose

使用Mongoose甚至Mongo可能会出现类似的情况吗?

Center.update({ghostBuster:{$exists}},{$set:{ectoplasm: this.exoplasm},$unset: {exoplasm:""}}, function(err, result){ })

我想更新一些记录并将一个字段移动到另一个字段,所以如果我可以在更新它时引用该获取的记录。在这种情况下,我将ectoplasm字段的值设为exoplasm

是否可以在没有在Mongoose Schema上定义钩子的情况下执行此操作?

1 个答案:

答案 0 :(得分:0)

使用mongo,您可以通过迭代从查询查询返回的游标(使用forEach()方法)并在循环内更新集合来完成此操作。例如:

db.centers.find({ 
    "ghostBuster": { "$exists": true } 
}).forEach(function(doc){
    db.centers.update(
        { "_id": doc._id },
        {
            "$set": { "ectoplasm": doc.exoplasm },
            "$unset": { "exoplasm": "" }
        }
    )
});

这"来回"到服务器将花费IO,所以你会尝试最小化它。使用 bulkWrite() 方法(如果使用MongoDB版本3.2)批量执行更新:

var ops = [];

db.centers.find({ 
    "ghostBuster": { "$exists": true } 
}).forEach(function(doc) {
    ops.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$set": { "ectoplasm": doc.exoplasm },
                "$unset": { "exoplasm": "" }
            }
        }
    });

    if (ops.length === 1000) {
        db.centers.bulkWrite(ops);
        ops = [];
    }
})

if (ops.length > 0)  db.centers.bulkWrite(ops);

或者对于MongoDB 2.6.x和3.0.x版本,请使用此版本的 Bulk operations

var bulk = db.centers.initializeUnorderedBulkOp(),
    counter = 0;

db.centers.find({ 
    "ghostBuster": { "$exists": true } 
}).forEach(function(doc) {
    bulk.find({ "_id": doc._id }).updateOne({
        "$set": { "ectoplasm": doc.exoplasm },
        "$unset": { "exoplasm": "" }
    });

    if (counter % 1000 === 0) {
        bulk.execute();
        bulk = db.centers.initializeUnorderedBulkOp();
    }
});

if (counter % 1000 !== 0 )  bulk.execute();

两种情况下的批量操作API都有助于减少服务器上的IO负载,方法是在集合中的每1000个文档中只发送一次请求进行处理。

对于Mongoose等价物,您可以实现类似下面的内容,使用Promises来处理node.js中批量API的异步性质。 要使用基础批量操作API,您应该通过mongoose模型中的.collection属性访问它。在使用API​​之前,请等待mongoose成功连接到db,因为Mongoose还没有真正支持"initializeOrderedBulkOp()"功能,因为它不能与mongoose的内部缓冲系统一起使用。

var mongoose = require('mongoose'),
    express = require('express'),
    Promise = require('bluebird'),
    Schema = mongoose.Schema;

function connect(uri, options){
    return new Promise(function(resolve, reject){
        mongoose.connect(uri, options, function(err){
            if (err) return reject(err);
            resolve(mongoose.connection);
        });
    });
}

var centerSchema = new Schema({
    exoplasm: Number,
    ghostBuster: Number,
    time: Date
}, { collection: "centers" });

var Center = mongoose.model("Center", centerSchema);

/*
function bulkUpdate(Model){    
    return new Promise(function(resolve, reject){
        var bulk = Model.collection.initializeUnorderedBulkOp(),
            counter = 0;

        Model.find({ "ghostBuster" : { "$exists": true } })
            .lean().exec(function (err, docs) {
            if (err) return reject(err);

            docs.forEach(function (doc){
                counter++;

                bulk.find({ "_id": doc._id }).updateOne({
                    "$set": { "ectoplasm": doc.exoplasm },
                    "$unset": { "exoplasm": "" }
                });

                if (counter % 500 == 0 ) {
                    bulk.execute(function(err, result) {
                        if (err) return reject(err);                        
                        bulk = Model.collection.initializeUnorderedBulkOp();                        
                        resolve(result);
                    });
                }                       
            });     

            if (counter % 500 != 0 ) {            
                bulkUpdateOps.execute(function(err, result) {
                    if (err) return reject(err);
                    resolve(result);
                });         
            }           
        });     
    });
}
*/

function bulkUpdate(Model){    
    return new Promise(function(resolve, reject){
        var ops = [],
            collection = Model.collection;

        Model.find({ "ghostBuster" : { "$exists": true } })
        .lean().exec(function (err, docs) {
            if (err) return reject(err);

            docs.forEach(function (doc){
                ops.push({
                    "updateOne": {
                        "filter": { "_id": doc._id },
                        "update": {
                            "$set": { "ectoplasm": doc.exoplasm },
                            "$unset": { "exoplasm": "" }
                        }
                    }
                });

                if (ops.length === 1000) {
                    collection.bulkWrite(ops, function(err, result) {
                        if (err) return reject(err);                        
                        ops = [];
                        resolve(result);
                    });
                }                       
            });     

            if (ops.length > 0) {            
                collection.bulkWrite(ops, function(err, result) {
                    if (err) return reject(err);
                    resolve(result);
                });         
            }           
        });     
    });
}


connect('mongodb://localhost/test', {}).then(function(db){
    bulkUpdate(Center).then(function(res){
        console.log('Bulk update complete.', res);      
    }, function(err){
        console.log('Bulk Error:', err);
        db.close();
    });
}, function(err){
    console.log('DB Error:', err);
});