gpt4 book ai didi

javascript - MongoDb 中的自动增量字段与异步批量插入

转载 作者:太空宇宙 更新时间:2023-11-04 01:02:47 25 4
gpt4 key购买 nike

我正在看这篇关于 MongoDb 中自动递增字段的文章。 http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

这在理论上似乎不错,但在我的应用程序中不起作用,因为所有数据库调用都是异步的。Ps,我使用 Mongoskin。考虑一下:

var getNextSequence function (name) {
db.counters.findAndModify({_id: 'invoiceNr'}, {}, {$inc: {seq: 1}}, {new: true}, function(err, doc) {
if (err) {
return next(err);
}
return doc.seq;
});
};

var seq = getNextSequence('invoiceNr');
console.log(seq);

这个(Console.log)在执行时当然不会有任何值(value)......

这让我考虑嵌套回调(经典的 Node 风格):

db.counters.findAndModify({_id: 'invoiceNr'}, {}, {$inc: {seq: 1}}, {new: true}, function(err, doc) {
if (err) {
return next(err);
}
var seq = getNextSequence('invoiceNr');
// Do something with the seq, like using it when inserting another document.
});

这对于一个文档来说效果很好,但是如果我进行批量插入(传递要插入的多个文档的数组),我看不出这是如何工作的。我需要批量插入。

回到循环和单个插入似乎不是一个好的解决方案。

你有什么好的解决办法吗?

最佳答案

因此文档建议使用 .findAndModify() 进行此类操作,因为“更新/增量”和检索结果的操作是“原子”操作。当然,如果您一次插入 500 个文档,您不想返回“获取下一个增量”500 次,因为那太疯狂了。但你在这个概念中遗漏了一些东西。

谁说必须增加1?简单地说,当您知道要插入 500 个项目时,您只需将当前计数器增加 501,以便下一个请求下一个计数器值的操作获取已经增加了 501 的值,因此该部分是好的。

现在您要求计数器增加 500 block ,您基本上只需使用它们即可。所以您知道要使用的第一个值基本上从返回值负 500 开始,并且您希望在实际返回的值上结束插入。

所以你想要一些像这样的代码:

var async = require('async'),
mongo = require('mongoskin'),
db = mongo.db('mongodb://localhost/test');


// The general incrementer

function getNextSequence( name, increment, callback ) {

// Handling passing in "increment" as optional
var args = Array.prototype.slice.call(arguments, 1);

callback = args.pop();
increment = args.length ? args.shift() || 1 : 1; // default 1

db.collection('counters').findAndModify(
{ "_id": name },
{},
{ "$inc": { "seq": increment } },
{ "new": true, "upsert": true },
function(err,doc) {
callback(err,doc.seq);
}
);

}

// Meat of your insertion logic

db.collection('target',function(err, collection) {

var arrayToInsert = []; // simulating, but 500 items long assumed
for (var x=0; x < 500; x++) {
arrayToInsert.push({
"x": x
});
}

var bulk = collection.initializeOrderedBulkOp();

async.waterfall(
[
function(callback) {
getNextSequence('invoiceNo',arrayToInsert.length + 1,callback);
},
function(seq,callback) {
var current = seq - arrayToInsert.length;
var index = 0;

async.whilst(
function() { return index < arrayToInsert.length },
function(callback) {
doc = arrayToInsert[index];
doc["invoice"] = current;
bulk.insert( doc );
index++;
current++
callback();
},
function(err) {
bulk.execute(callback);
}
);
}
],
function(err,result) {
if (err) throw err;
// Log BulkWrite result
console.log( JSON.stringify( result, undefined, 2 ) );
}
);

});

嗯,这是基本的模拟器,但您应该明白了。本质上,只需获取一个“值” block 来表示您要插入的条目数,并在插入实际文档时使用每个“值”。

最坏的情况?插入在某处失败,并且并非所有值都最终出现在文档中。所以呢?这并不重要,因为重点是您已经增加了计数器,并且没有其他进程可以从计数器中获取相同的“值”。

正如您从评论中可以了解到的,这就是我试图引导您的地方,您可能已经掌握了基础知识。没有任何内容表明您不能将该计数器增加超过 1,因此只需增加您想要的数量即可。

关于javascript - MongoDb 中的自动增量字段与异步批量插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25683274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com