Mongodb Mongo/Mongoose中自动增加文档编号
我的应用程序有几个用户,每个用户都有文档。每个文档都需要有一个序列号,可能看起来像这样:2013-1、2013-2(年份和序列号),或者可能只是一个简单的数字:1、2、3 目前,在创建Mongoose文档时,我正在根据用户设置分配序列号。根据用户设置中的序列号和编号格式,我将生成最终的文档编号 我意识到,当同时创建两个文档时,它们将得到完全相同的编号,因为我在保存一个文档后,正在增加设置中的序列号。但我在创建(尚未保存)文档时分配序列号,因此两个文档的序列号将完全相同 我显然需要一种方法来处理这个序列号在保存时自动递增 如何确保该数字是唯一的并自动递增/生成?此代码取自手册,它实际上描述了如何使_id字段自动递增。但是,它可以应用于任何领域。您要做的是在插入文档之后检查数据库中是否存在插入的值。如果已插入,请重新增加该值,然后再次尝试插入。通过这种方式,您可以检测双精度值并重新增加它们Mongodb Mongo/Mongoose中自动增加文档编号,mongodb,mongoose,Mongodb,Mongoose,我的应用程序有几个用户,每个用户都有文档。每个文档都需要有一个序列号,可能看起来像这样:2013-1、2013-2(年份和序列号),或者可能只是一个简单的数字:1、2、3 目前,在创建Mongoose文档时,我正在根据用户设置分配序列号。根据用户设置中的序列号和编号格式,我将生成最终的文档编号 我意识到,当同时创建两个文档时,它们将得到完全相同的编号,因为我在保存一个文档后,正在增加设置中的序列号。但我在创建(尚未保存)文档时分配序列号,因此两个文档的序列号将完全相同 我显然需要一种方法来处理这
while (1) {
var cursor = targetCollection.find( {}, { f: 1 } ).sort( { f: -1 } ).limit(1);
var seq = cursor.hasNext() ? cursor.next().f + 1 : 1;
doc.f = seq;
targetCollection.insert(doc);
var err = db.getLastErrorObj();
if( err && err.code ) {
if( err.code == 11000 /* dup key */ )
continue;
else
print( "unexpected error inserting data: " + tojson( err ) );
}
break;
}
在本例中,f是文档中要自动递增的字段。要实现这一点,您需要使字段唯一,这可以通过索引来完成
db.myCollection.ensureIndex( { "f": 1 }, { unique: true } )
@emre和@wiredpaire为我指明了正确的方向,但我想为我的问题提供一个完全兼容猫鼬的答案。我最终得到了以下解决方案:
var设置=新架构({
nextSeqNumber:{type:Number,默认值:1}
});
var Document=新模式({
_userId:{type:Schema.Types.ObjectId,ref:“User”},
编号:{type:String}
});
//在_userId和文档编号上创建复合唯一索引
索引({u userId:1,“number:1},{unique:true});
//我确保这是最后一个预保存中间件(以防万一)
Document.pre('save',函数(下一步){
var doc=这个;
//你必须知道设置id,对我来说,我将其存储在内存中:app.current.settings.id
Settings.findByIdAndUpdate(Settings_id,{$inc:{nextSeqNumber:1}},函数(err,Settings){
如果(错误)下一个(错误);
doc.number=settings.nextSeqNumber-1;//减1,因为我需要的是“当前”序列号,而不是下一个序列号
next();
});
});
请注意,使用此方法无法要求架构中的数字路径,也没有点,因为它是自动添加的。您可以通过以下方式实现:
var mongoose=require('mongoose');
猫鼬mongodb://localhost/todoApp');
//创建一个序列
函数序列生成器(名称){
var-SequenceSchema,Sequence;
SequenceSchema=新的mongoose.Schema({
nextSeqNumber:{type:Number,默认值:1}
});
Sequence=mongoose.model(name+‘Seq’,SequenceSchema);
返回{
下一步:函数(回调){
Sequence.find(函数(错误、数据){
如果(错误){抛出(错误);}
如果(数据长度<1){
//如果不存在则创建首先创建并返回
创建({},函数(err,seq){
如果(错误){抛出(错误);}
回调(seq.nextSeqNumber);
});
}否则{
//更新序列并返回下一步
Sequence.findByIdAndUpdate(数据[0]。_id,{$inc:{nextSeqNumber:1}},函数(err,seq){
如果(错误){抛出(错误);}
回调(seq.nextSeqNumber);
});
}
});
}
};
}
//序列实例
var序列=序列生成器(“todo”);
var TodoSchema=newmongoose.Schema({
名称:String,
已完成:布尔,
优先权:数量,
注意:{type:String,默认值:''},
更新位置:{type:Date,默认值:Date.now}
});
TodoSchema.pre('save',函数(下一步){
var doc=这个;
//获取下一个序列
sequence.next(函数(nextSeq){
doc.priority=nextSeq;
next();
});
});
var Todo=mongoose.model('Todo',TodoSchema);
您可以在节点控制台中进行测试,如下所示
函数cb(err,data){console.log(err,data);}
create({name:'hola'},cb);
Todo.find(cb);
对于每个新创建的对象,您将看到优先级增加。干杯 您可以按如下方式使用
mongoose auto increment
包:
var mongoose = require('mongoose');
var autoIncrement = require('mongoose-auto-increment');
/* connect to your database here */
/* define your DocumentSchema here */
autoIncrement.initialize(mongoose.connection);
DocumentSchema.plugin(autoIncrement.plugin, 'Document');
var Document = mongoose.model('Document', DocumentSchema);
您只需要初始化一次
自动增量
。Hmm,这可能行得通,但您知道我将如何使用Mongoose实现thsi吗?此外,我需要确保文档编号在一个用户的上下文中是唯一的。可以有2个用户,两个用户都只能有一个文档,编号为1。因此,独特的索引应该考虑数字和用户ID。[DOCS]hhttp://www.wiredprairie.us/blog/index.php/archives/1524)有两个很好的例子。您可以使用计数器示例,为用户Id添加一个辅助密钥,使其每个用户都是唯一的!要详细说明为什么会这样,您需要一个阻塞操作(例如写操作),以便异步save()
调用按顺序进行。使用Find或Count对要递增的集合进行查找或计数的“更简单”解决方案失败了,因为Find和Count都是非阻塞(读取命令),所以您不能依靠它们(可能)连续执行多个异步save()
调用。感谢您发布代码示例,这看起来也是我一直在寻找的解决方案。如果这对任何人都有用,我