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 是保证唯一的,虽然不是自增。
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();
解释
- 创建计数器集合:我们首先创建一个名为
Counter
的集合,用于存储自增的序列号。 - 用户模型:定义了一个
User
模型,其中包含一个userId
字段,其默认值为 0。 - 中间件:在
User
模型中添加了一个pre('save')
中间件。每当新用户保存到数据库时,该中间件会执行:- 查询并更新
Counter
集合中的seq
字段,使其加 1。 - 将更新后的
seq
值赋给userId
。
- 查询并更新
- 创建用户:通过调用
createUser
函数创建一个新的用户,并打印出用户的userId
。
这种方法可以确保每次插入新用户时,userId
都是唯一的且按顺序递增的整数。
请注意,这种方法依赖于 MongoDB 的原子操作来保证自增的正确性,因此在高并发场景下可能会有一些限制。