mysql 如何在MongoDB中实现自动递增的主ID?

ubbxdtey  于 2023-03-28  发布在  Mysql
关注(0)|答案(7)|浏览(193)

就像在MySQL中一样,我需要一个递增的ID。

lyr7nygr

lyr7nygr1#

您需要使用MongoDB的findAndModify命令。使用它,您可以原子地选择和递增字段。

db.seq.findAndModify({
  query: {"_id": "users"},
  update: {$inc: {"seq":1}},
  new: true
});

这将增加users集合的计数器,然后可以在插入之前将其添加到文档中。由于它是原子的,因此不必担心竞争条件导致ID冲突。
它不像MySQL的auto_increment标志那样无缝,但您通常也可以选择在Mongo驱动程序中指定自己的ID工厂,因此您可以实现一个使用findAndModify透明地递增和返回ID的工厂,从而获得更像MySQL的体验。
这种方法的缺点是,由于每个插入都依赖于序列集合上的写锁,如果你做了很多写操作,你可能很快就会遇到瓶颈。如果你只是想保证集合中的文档按插入顺序排序,那么看看Capped Collections

kuuvgm7e

kuuvgm7e2#

MongoDB的目的是水平伸缩。在这种情况下,自动递增会导致id冲突。这就是为什么id看起来更像guid/uuid。

jk9hmnmh

jk9hmnmh3#

MongoDB提供了两种方式来自动递增**_id***(或自定义键)*。

  • 使用计数器集合
  • 乐观循环

计数器集合

在这里,我们需要创建一个集合,它存储了键的最大数量,并且每次调用这个函数时递增1。

1.存储功能

function getNextSequence(collectionName) {
   var ret = db.counters.findAndModify({
               query: { _id: collectionName },
               update: { $inc: { seq: 1 } },
               new: true,
               upsert: true
             });

   return ret.seq;
}

2.插入文件

db.users.insert({
  _id: getNextSequence("USER"),
  name: "Nishchit."
})

乐观循环

在此模式中,乐观循环计算increased_id值,并尝试插入具有计算出的_id值的文档。如果插入成功,则循环结束。否则,循环将迭代可能的_id值,直到插入成功。

1.存储功能

function insertDocument(doc, targetCollection) {

    while (1) {

        var cursor = targetCollection.find( {}, { _id: 1 } ).sort( { _id: -1 } ).limit(1);

        var seq = cursor.hasNext() ? cursor.next()._id + 1 : 1;

        doc._id = seq;

        var results = targetCollection.insert(doc);

        if( results.hasWriteError() ) {
            if( results.writeError.code == 11000 /* dup key */ )
                continue;
            else
                print( "unexpected error inserting data: " + tojson( results ) );
        }

        break;
    }
}

2.插入文件

var myCollection = db.USERS;

insertDocument(
   {
     name: "Nishchit Dhanani"
   },
   myCollection
);

官方文档来自MongoDB

6ss1mwsb

6ss1mwsb4#

如果您怀疑您的数据可能跨越多个服务器(也称为分片),那么请使用Dennis并使用本地ObjectId。
如果您更喜欢int/long id(在url上看起来更好)然后你可以像Chris建议的那样使用findAndModify开始简单的实现一个生成器。当/如果性能/锁定开始成为一个问题,你可以升级你的生成器来实现Hi/Lo算法。这将大大减少'seq'集合的压力。实际上消除了这个问题。(客户端生成器正在使用“池”,并且仅在没有更多空闲ID时才联系DB)

eagi6jfj

eagi6jfj5#

虽然不支持自动增量,但您可以轻松实现自己的小类来发布增量值。
我自己也需要这个特性,所以我用php写了一个小类。

zf9nrax1

zf9nrax16#

@TIMEX:如果您正在寻找序列号而不是ID(因为ID由mongo保留),请检查下面的链接是否可以帮助您
http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/#auto-increment-counters-collection
@Dennis Burton自动递增如果用户这样做,它不会导致冲突吗?我觉得,因此mongo db使用自己的_Id,所以它可以避免冲突,但如果用户希望有一个列作为运行序列,他们可以自由地拥有它

ogq8wdun

ogq8wdun7#

我用的是-mongoose-auto-increment

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    autoIncrement = require('mongoose-auto-increment');

var connection = mongoose.createConnection("mongodb://localhost/myDatabase");

autoIncrement.initialize(connection);

var bookSchema = new Schema({
    author: { type: Schema.Types.ObjectId, ref: 'Author' },
    title: String,
    genre: String,
    publishDate: Date
});

bookSchema.plugin(autoIncrement.plugin, 'Book');
var Book = connection.model('Book', bookSchema);

相关问题