讨论:Nodejs中mongodb的id自增处理

讨论:Nodejs中mongodb的id自增处理

话说mongodb的id没法自动递增提供了个_id也不知道怎么获取对象的字符串来用。先说说我的方法吧定义了一个ids表用来存放控制所有表的id,下面代码是Model部分

function Ids(tablename, id) {
    this.id = id;
    this.tablename = tablename;
}
module.exports = Ids;
Ids.getId = function (tablename, callback) {
    mongodb.open(function (err, db) {
    db.collection('ids', function (err, collection) {
        collection.findAndModify({"tablename":tablename}, [], {$inc:{'id':1}}, {new:true, upsert:true}, function (err, doc) {
            mongodb.close();
            callback(doc.id);
            });
        });
    });
}

各位攻城狮你们怎么处理的啊


15 回复

讨论:Nodejs中MongoDB的ID自增处理

在使用MongoDB时,我们经常遇到需要生成自增ID的需求。然而,MongoDB本身并不支持传统的自增ID功能(如SQL数据库中的AUTO_INCREMENT)。因此,我们需要通过其他方式实现这一需求。

方法一:使用单独的ID表

一种常见的方法是使用一个单独的集合来管理所有的ID。每当需要生成新的ID时,从该集合中获取并更新当前的ID值。下面是一个具体的实现示例:

// 定义一个Id管理类
function Ids(tablename, id) {
    this.id = id;
    this.tablename = tablename;
}

module.exports = Ids;

// 获取下一个ID的方法
Ids.prototype.getNextId = function (callback) {
    const MongoClient = require('mongodb').MongoClient;
    const url = 'mongodb://localhost:27017'; // MongoDB连接URL

    MongoClient.connect(url, function (err, client) {
        if (err) {
            console.error('MongoDB连接错误:', err);
            return callback(null); // 返回null表示出错
        }
        
        const db = client.db('testdb'); // 连接到指定的数据库
        const collection = db.collection('ids');

        collection.findOneAndUpdate(
            { tablename: this.tablename }, 
            { $inc: { id: 1 } },
            { returnOriginal: false },
            function (err, doc) {
                if (err) {
                    console.error('查询或更新ID时发生错误:', err);
                    client.close();
                    return callback(null);
                }

                const nextId = doc.value ? doc.value.id : null;
                client.close();
                callback(nextId);
            }
        );
    });
};

// 使用示例
const IdsModel = require('./Ids');
const idsModel = new IdsModel('mycollection', 1);

idsModel.getNextId((nextId) => {
    console.log('获取到的新ID:', nextId);
});

在这个示例中,我们首先定义了一个Ids类,并在其中实现了一个getNextId方法。该方法通过调用findOneAndUpdate方法来查找并更新指定表名的ID值。每次调用该方法时,都会将该表对应的ID值加1,并返回新生成的ID。

方法二:使用MongoDB的内置函数

另一种方法是利用MongoDB的内置函数,例如使用findAndModify方法。这种方法与上述方法类似,但可能更简洁一些。具体实现可以参考官方文档进行调整。

总结

以上两种方法都可以有效地实现MongoDB中的自增ID功能。选择哪种方法取决于你的具体需求和应用场景。无论采用哪种方法,都需要确保在多线程或多进程环境中正确处理并发问题,以避免ID重复的情况发生。

希望这些示例能帮助你更好地理解和实现Node.js中MongoDB的ID自增功能。


也是这么做的。$inc是原子操作,所以不用担心并发问题。

我是mongo初学者,用的是mongoose,我用_id来find好像找不到,是不是mongo内的id最好还是我们自己设置一个字段来读取啊?

_id是一个mongo数据库的对象而不是一个数字或字符串类型

什么意思,为什么要自己处理ID?

用了你就知道了,我也希望能通过_id来操作,可是技术水平不够啊

我运行,没有成功,后台没有输出任何东西。另外,这个的原理是不是,存的每个表的最大的ID。

{_id : ObjectId(‘50a213a7637ffa4155b77f73’)}

楼主好啊,这个可以用在给发布的博客添加id吗

你好啊,大哥,可以请教您一下吗

弱弱的问问tablename是什么意思,如果想在一张表格中存三个不同的自增id,比如会员id,博客id,应该如何处理呢

遇到同样的问题,学习下,谢谢

在Node.js中使用MongoDB时,通常不需要手动实现ID的自增功能,因为MongoDB自带的_id字段就是一个全局唯一的ObjectId。不过,如果你确实需要一个自增的ID,可以采用类似帖子中提到的方法,通过维护一个单独的集合来管理ID。

示例代码

const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;

const url = 'mongodb://localhost:27017';
const dbName = 'yourDatabaseName';

// 定义Id模型
function Ids(tablename, id) {
    this.id = id;
    this.tablename = tablename;
}

// 获取下一个ID的方法
Ids.prototype.getNextId = async function (tablename) {
    const client = await MongoClient.connect(url);
    const db = client.db(dbName);

    try {
        const result = await db.collection('ids').findOneAndUpdate(
            { tablename },
            { $inc: { id: 1 } },
            { upsert: true, returnDocument: 'after' }
        );

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

// 使用示例
(async () => {
    const newId = await new Ids().getNextId('yourCollectionName');
    console.log(newId);
})();

解释

  1. 定义模型:定义了一个Ids构造函数,用于存储表名和当前ID。
  2. 获取ID:定义了getNextId方法,该方法连接到数据库并更新ids集合中的指定表名对应的ID,如果不存在则插入并设置初始值为1。
  3. 异步操作:由于数据库操作是异步的,因此使用async/await语法来简化代码。
  4. 关闭连接:确保在完成操作后关闭数据库连接。

这种方法虽然能实现自增ID的需求,但在高并发情况下可能会遇到ID冲突的问题。因此,实际生产环境中建议使用MongoDB默认的ObjectId作为唯一标识符。

回到顶部