【问题标题】:Create unique autoincrement field with mongoose [duplicate]使用 mongoose 创建唯一的自动增量字段 [重复]
【发布时间】:2014-06-05 15:22:46
【问题描述】:

给定一个架构:

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

我想让id 独一无二且自动递增。我试图实现mongodb implementation,但在理解如何在猫鼬中正确地做到这一点时遇到了问题。

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

【问题讨论】:

  • 我真的花了很多时间尝试自己做。很抱歉提出这样一个愚蠢的问题
  • 我尝试在保存前增加 id。但是我必须如何处理计数器集合?我必须有它的架构吗?这是我想不通的问题

标签: node.js mongodb mongoose auto-increment database


【解决方案1】:
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();
    }
});

【讨论】:

【解决方案2】:

是的,这是该功能的“瘦身”。

您需要在您的 mongo 数据库中拥有该集合。如果您愿意,它可以作为并发密钥分配的单一真实记录。 Mongo 的示例向您展示了如何执行“原子”操作来获取下一个键,并确保即使有并发请求,您也可以保证返回唯一键而不会发生冲突。

但是,mongodb 本身并没有实现该机制,它们会向您展示如何做到这一点。它们仅提供 _id 用作唯一文档键。我希望这可以阐明您的方法。

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

【讨论】:

    【解决方案3】:

    你可以使用它。 这个包每次都会为此产生独特的价值。

    包名:uniqid

    链接:https://www.npmjs.com/package/uniqid

    【讨论】:

    • 使用它而不是 Mongo 的原生 ObjectId 有什么意义?该包还生成一个长标识符,并且 OP 可能想要一些简短易读的东西,否则他们会使用 ObjectId,它也是始终递增的,而不是 1。
    【解决方案4】:

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

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

    【讨论】:

    • 其实这是一个不好的方法,应该忽略,他请求的操作类型需要是原子的。在并发请求的情况下,您可以轻松获得两次相同的 id。
    • 是的!这不是生产就绪型应用的解决方案。
    • 如果服务器压力大,您建议的操作可能会无人看管......该操作是大分子而不是原子
    猜你喜欢
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 2015-03-06
    相关资源
    最近更新 更多