使用mongoose创建唯一的自增字段

26

给定一个模式:

var EventSchema = new Schema({
    id: {
        // ...
    },
    name: {
        type: String
    },
});

我想使id唯一并自动递增。我尝试实现mongodb实现,但不理解如何在mongoose中正确实现。

我的问题是: 在不使用任何插件等情况下,在mongoose中实现自动递增字段的正确方法是什么?


我真的花了很多时间并尝试自己做。对于这样一个愚蠢的问题感到抱歉。 - Boris Zagoruiko
我尝试在保存之前递增ID。但是我该如何处理计数器集合?我需要为此编写模式吗?这是我无法解决的问题。 - Boris Zagoruiko
4个回答

5
const ModelIncrementSchema = new Schema({
    model: { type: String, required: true, index: { unique: true } },
    idx: { type: Number, default: 0 }
});

ModelIncrementSchema.statics.getNextId = async function(modelName, callback) {
    let incr = await this.findOne({ model: modelName });

    if (!incr) incr = await new this({ model: modelName }).save();
    incr.idx++;
    incr.save();
    return incr.idx;
};


const PageSchema = new Schema({
    id: { type: Number ,  default: 0},
    title: { type: String },
    description: { type: String }
});


PageSchema.pre('save', async function(next) {
    if (this.isNew) {
        const id = await ModelIncrement.getNextId('Page');
        this.id = id; // Incremented
        next();
    } else {
        next();
    }
});

3
“仅代码答案”可以通过解释代码的工作原理来改进! - Dan Dascalescu

1

是的,这就是该功能的“内幕”。

您需要在Mongo数据库中拥有该集合。如果您想要并发密钥分配单个记录的真实性,它将充当并发密钥分配单个记录的真实性。Mongo的示例向您展示了如何执行“原子”操作以获取下一个密钥,并确保即使存在并发请求,您也将获得唯一密钥而不会发生冲突。

但是,MongoDB没有本地实现该机制,他们向您展示如何实现它。他们只提供_id用作唯一文档键。我希望这澄清了您的方法。

为了扩展这个想法,请继续将mongo建议的实现添加到您定义的Mongoose模型中,并像您已经猜测的那样,在保存到mongo之前在Pre-save或更好的pre-init事件中使用它以确保您始终在服务器端使用集合时生成id。


-1

1
使用那个包的意义是什么,而不是使用Mongo的本地ObjectId?该包也会生成一个长标识符,而OP可能想要一些短且易读的东西,否则他们会使用ObjectId,它也总是递增的,只是不是递增1。 - Dan Dascalescu

-5

忽略以上所有内容。这里是解决方案

YourModelname.find().count(function(err, count){
   req["body"].yourID= count + 1;
      YourModelname.create(req.body, function (err, post) {
        if (err) return next(err);
        res.json(req.body);
      });
    });

3
实际上,这种方法是不好的,应该忽略掉。他所请求的操作类型需要是原子的。如果存在并发请求,很容易会获得两次相同的ID。 - naor.z
1
是的!这不是生产应用程序的解决方案。 - Prathamesh More
如果服务器压力很大,您建议的操作可能会被忽略...该操作是一个宏分子而不是原子。 - Aloy A Sen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接