Nodejs mongoose的Schema能不能设自id自增长int类型?

Nodejs mongoose的Schema能不能设自id自增长int类型?

如果有像cnodejs的models怎样修改呢?

4 回复

当然可以。在使用 Mongoose 构建 Node.js 应用时,有时我们可能需要一个自增的整数作为文档的唯一标识符。尽管 Mongoose 的默认 _id 字段是一个 MongoDB 的 ObjectId 类型,但我们可以创建一个自定义的 Schema 并实现自增功能。

示例代码

首先,我们需要设置一个集合来存储当前的序列号。然后,在插入新文档时,我们将从该集合中获取下一个序列号并将其作为文档的一部分保存。

步骤 1: 创建序列号集合

const mongoose = require('mongoose');

const sequenceSchema = new mongoose.Schema({
    _id: { type: String, required: true },
    seq: { type: Number, default: 0 }
});

const SequenceModel = mongoose.model('sequence', sequenceSchema);

步骤 2: 创建一个生成器函数

async function getNextSequenceValue(sequenceName) {
    const result = await SequenceModel.findOneAndUpdate(
        { _id: sequenceName },
        { $inc: { seq: 1 } },
        { new: true, upsert: true }
    );
    return result.seq;
}

步骤 3: 定义你的模型

const userSchema = new mongoose.Schema({
    userId: { type: Number, unique: true },
    name: String,
    email: String
});

userSchema.pre('save', async function (next) {
    if (!this.userId) {
        this.userId = await getNextSequenceValue('userId');
    }
    next();
});

const UserModel = mongoose.model('User', userSchema);

使用模型

// 插入新用户
const newUser = new UserModel({ name: 'John Doe', email: 'john@example.com' });
await newUser.save();

console.log(newUser.userId); // 输出自增的用户ID

解释

  • 序列号集合:我们创建了一个名为 sequence 的集合,用于存储每个序列号的当前值。
  • 生成器函数getNextSequenceValue 函数负责更新序列号,并返回下一个值。
  • 预保存钩子:在用户模型保存之前,我们检查 userId 是否已经存在。如果不存在,则调用 getNextSequenceValue 获取下一个序列号并赋值给 userId

通过这种方式,我们可以为我们的 Mongoose 模型实现一个简单的自增整数 ID 功能。


默认自带的_id 是保证唯一的,虽然不是自增。

可以 首先:建立一个存放自增长ID的model var mongoose = require(‘mongoose’) ,Schema = mongoose.Schema;

var KeysSchema = new Schema({ _id: {type: String ,index: true}, //实例应该是你的其它model的名字 key: {type: Number,default: 0} //每次使用时的自增长ID });

mongoose.model(‘Keys’,KeysSchema);

以下是每次想生成自增长的ID时。调用的方法,keyId就是存放在KeysScheam中的_id值,如果你有三个model那么 _id可能是:personAutoId,replyAutoId,msgAutoId,用这三个关键字来存储每个model的名字 key默认从0开始,当然你也可以设置为从1000开始,当call下面这个方法后,如果从来没有为任何一个model生成过自增长的ID,那就是默认返回的0,如果以前自增长过,那就会:$inc这个Number类型的key。

以此来实现自增长ID,即:先保存自增长ID的model名字,然后再$inc

var addAndUpdateKeys = exports.addAndUpdateKeys = function(keyId,callback){ Keys.findById(keyId,function(err,doc){ if(!err && !doc){ var obj = {}; obj._id = keyId; var keys = new Keys(obj); keys.save(function(err,doc){ if(err){ callback(null); return; } callback(doc); }) }else{ Keys.findByIdAndUpdate(keyId,{$inc:{key: 1}}, function(err,doc){ if(err){ callback(null); return; } callback(doc); }) } }); };

Node.js 中使用 Mongoose 时,默认情况下,Mongoose 会为每个文档生成一个 _id 字段,该字段是 MongoDB 自动生成的唯一 ObjectId 类型。如果你确实需要一个自增的整数作为主键,可以通过自定义方法来实现。

示例代码

以下是一个简单的示例,展示如何在 Mongoose 中实现一个自增的整数字段:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// 创建一个计数器集合
const counterSchema = new Schema({
    _id: { type: String, required: true },
    seq: { type: Number, default: 0 }
});

const Counter = mongoose.model('Counter', counterSchema);

// 创建一个用户模型,包含自增的整数字段
const userSchema = new Schema({
    userId: { type: Number, default: 0 }
});

userSchema.pre('save', async function (next) {
    if (this.isNew) {
        const counter = await Counter.findOneAndUpdate(
            { _id: 'userId' },
            { $inc: { seq: 1 } },
            { new: true }
        );
        this.userId = counter.seq;
    }
    next();
});

const User = mongoose.model('User', userSchema);

// 使用模型
async function createUser() {
    const newUser = new User();
    await newUser.save();
    console.log(newUser.userId);
}

createUser();

解释

  1. 创建计数器集合:我们首先创建一个名为 Counter 的集合,用于存储自增的序列号。
  2. 用户模型:定义了一个 User 模型,其中包含一个 userId 字段,其默认值为 0。
  3. 中间件:在 User 模型中添加了一个 pre('save') 中间件。每当新用户保存到数据库时,该中间件会执行:
    • 查询并更新 Counter 集合中的 seq 字段,使其加 1。
    • 将更新后的 seq 值赋给 userId
  4. 创建用户:通过调用 createUser 函数创建一个新的用户,并打印出用户的 userId

这种方法可以确保每次插入新用户时,userId 都是唯一的且按顺序递增的整数。

请注意,这种方法依赖于 MongoDB 的原子操作来保证自增的正确性,因此在高并发场景下可能会有一些限制。

回到顶部