Nodejs中mongodb的自增益问题

Nodejs中mongodb的自增益问题

我想实现一个 { “name” : “test1”, “uid”:0 } { “name” : “test2”, “uid”:1 } { “name” : “test3”, “uid”:2 } 这种uid每次添加都会自动增加, 请问下有什么快捷方法吗,我之前解决方法是先查找一次最后添加的uid,然后在这个基础上面+1操作,在存储。

11 回复

在Node.js中使用MongoDB时,实现自动递增的uid确实是一个常见的需求。你提到的方法(即先查找最大的uid,然后加一)虽然可行,但在高并发场景下可能会出现问题,因为两个并发请求可能同时查到相同的最大值,导致重复的uid

使用MongoDB的findAndModify方法

MongoDB提供了一个原子操作findAndModify,可以用来更新文档并返回更新前或后的文档。这正是我们所需要的,因为它确保了操作的原子性,避免了并发问题。

示例代码

首先,确保你已经安装了MongoDB驱动程序:

npm install mongodb

然后,你可以使用以下代码来实现自动递增的uid

const { MongoClient } = require('mongodb');

async function getNextUid() {
    const uri = "your_mongodb_connection_string";
    const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

    try {
        await client.connect();
        const database = client.db('your_database_name');
        const collection = database.collection('your_collection_name');

        // 使用 findAndModify 方法获取并递增 uid
        const result = await collection.findAndModify(
            {}, // 空查询条件,表示没有特定的过滤条件
            [], // 按什么排序,空数组表示不排序
            [{ $inc: { uid: 1 } }], // 更新操作
            { new: true }, // 返回更新后的文档
            { upsert: true } // 如果没有找到匹配的文档,则插入一个新的
        );

        return result.value.uid;
    } finally {
        await client.close();
    }
}

// 调用函数
getNextUid().then(uid => console.log(`Next UID is ${uid}`));

解释

  • findAndModify方法允许你在单个操作中查找、修改和返回文档。
  • { $inc: { uid: 1 } } 表示将uid字段的值增加1。
  • { new: true } 参数确保返回的是更新后的文档。
  • { upsert: true } 参数确保如果找不到任何匹配的文档,会插入一个新文档,其uid为1。

这种方法保证了uid的唯一性和顺序性,并且处理了并发问题。


沒有 只能這樣

啊~只有这样啊~总感觉多查找了一次数据库~~

可以建一个sequence表,每次增加的那个值存在里面。用的时候+1取出,再存入。

楼上一样是要多访问一次I/O

mongo原生貌似做不到,2楼的方法可以试试

谢谢~认真看了很好用

无法理解这种需求啊。。。自带的 _id 难道不够好吗

我主要是想查找时方便,例如一个新闻列表,觉得_id 太长了,希望例如通过url new/1,new/2,这样查找

在Node.js中使用MongoDB实现自增ID的功能,可以利用MongoDB的原子操作来确保数据的一致性。下面是一种常见的做法,通过创建一个单独的集合来存储序列号(例如counters),每次插入新文档时,都从这个集合中获取下一个序列号。

首先,你需要安装mongoose库来方便地操作MongoDB:

npm install mongoose

接下来是具体的代码实现:

1. 创建序列号管理模型

const mongoose = require('mongoose');

// 定义计数器模型
const counterSchema = new mongoose.Schema({
    _id: String,
    sequence_value: { type: Number, default: 0 }
});

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

2. 实现自增函数

async function getNextSequenceValue(sequenceName) {
    const filter = { _id: sequenceName };
    const update = { $inc: { sequence_value: 1 } };
    const options = { upsert: true, returnOriginal: false };

    const result = await Counter.findOneAndUpdate(filter, update, options);
    return result.sequence_value;
}

3. 插入新文档时使用自增ID

async function createDocument(name) {
    // 获取下一个sequence值
    const uid = await getNextSequenceValue('uid');
    
    // 插入新的文档
    const newDoc = { name, uid };
    await YourModel.create(newDoc);
}

4. 初始化计数器

在你的应用启动时,确保初始化counters集合:

async function initCounter() {
    try {
        await Counter.create({ _id: 'uid', sequence_value: 0 });
        console.log("Counter initialized successfully.");
    } catch (error) {
        console.error("Failed to initialize counter:", error);
    }
}

// 在应用启动时调用此函数
initCounter();

以上就是如何在Node.js中通过Mongoose实现MongoDB自增ID的一种方法。这种方法避免了多次查询数据库的问题,并且能够确保自增的原子性。

回到顶部