Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb Mongo/Mongoose中自动增加文档编号_Mongodb_Mongoose - Fatal编程技术网

Mongodb Mongo/Mongoose中自动增加文档编号

Mongodb Mongo/Mongoose中自动增加文档编号,mongodb,mongoose,Mongodb,Mongoose,我的应用程序有几个用户,每个用户都有文档。每个文档都需要有一个序列号,可能看起来像这样:2013-1、2013-2(年份和序列号),或者可能只是一个简单的数字:1、2、3 目前,在创建Mongoose文档时,我正在根据用户设置分配序列号。根据用户设置中的序列号和编号格式,我将生成最终的文档编号 我意识到,当同时创建两个文档时,它们将得到完全相同的编号,因为我在保存一个文档后,正在增加设置中的序列号。但我在创建(尚未保存)文档时分配序列号,因此两个文档的序列号将完全相同 我显然需要一种方法来处理这

我的应用程序有几个用户,每个用户都有文档。每个文档都需要有一个序列号,可能看起来像这样:2013-1、2013-2(年份和序列号),或者可能只是一个简单的数字:1、2、3

目前,在创建Mongoose文档时,我正在根据用户设置分配序列号。根据用户设置中的序列号和编号格式,我将生成最终的文档编号

我意识到,当同时创建两个文档时,它们将得到完全相同的编号,因为我在保存一个文档后,正在增加设置中的序列号。但我在创建(尚未保存)文档时分配序列号,因此两个文档的序列号将完全相同

我显然需要一种方法来处理这个序列号在保存时自动递增

如何确保该数字是唯一的并自动递增/生成?

此代码取自手册,它实际上描述了如何使_id字段自动递增。但是,它可以应用于任何领域。您要做的是在插入文档之后检查数据库中是否存在插入的值。如果已插入,请重新增加该值,然后再次尝试插入。通过这种方式,您可以检测双精度值并重新增加它们

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();
});
});

请注意,使用此方法无法要求架构中的数字路径,也没有点,因为它是自动添加的。

您可以通过以下方式实现:

  • 创建序列生成器,它只是另一个保存最后一个数字的计数器的文档
  • 使用mongoose中间件更新所需字段的自动增量
  • 下面是一个todo应用程序的工作和测试示例

    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()
    调用。感谢您发布代码示例,这看起来也是我一直在寻找的解决方案。如果这对任何人都有用,我