就像在MySQL中一样,我需要一个递增的ID。
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。
users
auto_increment
kuuvgm7e2#
MongoDB的目的是水平伸缩。在这种情况下,自动递增会导致id冲突。这就是为什么id看起来更像guid/uuid。
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值,直到插入成功。
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; } }
var myCollection = db.USERS; insertDocument( { name: "Nishchit Dhanani" }, myCollection );
官方文档来自MongoDB。
6ss1mwsb4#
如果您怀疑您的数据可能跨越多个服务器(也称为分片),那么请使用Dennis并使用本地ObjectId。如果您更喜欢int/long id(在url上看起来更好)然后你可以像Chris建议的那样使用findAndModify开始简单的实现一个生成器。当/如果性能/锁定开始成为一个问题,你可以升级你的生成器来实现Hi/Lo算法。这将大大减少'seq'集合的压力。实际上消除了这个问题。(客户端生成器正在使用“池”,并且仅在没有更多空闲ID时才联系DB)
eagi6jfj5#
虽然不支持自动增量,但您可以轻松实现自己的小类来发布增量值。我自己也需要这个特性,所以我用php写了一个小类。
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,所以它可以避免冲突,但如果用户希望有一个列作为运行序列,他们可以自由地拥有它
ogq8wdun7#
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);
7条答案
按热度按时间lyr7nygr1#
您需要使用MongoDB的findAndModify命令。使用它,您可以原子地选择和递增字段。
这将增加
users
集合的计数器,然后可以在插入之前将其添加到文档中。由于它是原子的,因此不必担心竞争条件导致ID冲突。它不像MySQL的
auto_increment
标志那样无缝,但您通常也可以选择在Mongo驱动程序中指定自己的ID工厂,因此您可以实现一个使用findAndModify透明地递增和返回ID的工厂,从而获得更像MySQL的体验。这种方法的缺点是,由于每个插入都依赖于序列集合上的写锁,如果你做了很多写操作,你可能很快就会遇到瓶颈。如果你只是想保证集合中的文档按插入顺序排序,那么看看Capped Collections。
kuuvgm7e2#
MongoDB的目的是水平伸缩。在这种情况下,自动递增会导致id冲突。这就是为什么id看起来更像guid/uuid。
jk9hmnmh3#
MongoDB提供了两种方式来自动递增**_id***(或自定义键)*。
计数器集合
在这里,我们需要创建一个集合,它存储了键的最大数量,并且每次调用这个函数时递增1。
1.存储功能
2.插入文件
乐观循环
在此模式中,乐观循环计算increased_id值,并尝试插入具有计算出的_id值的文档。如果插入成功,则循环结束。否则,循环将迭代可能的_id值,直到插入成功。
1.存储功能
2.插入文件
官方文档来自MongoDB。
6ss1mwsb4#
如果您怀疑您的数据可能跨越多个服务器(也称为分片),那么请使用Dennis并使用本地ObjectId。
如果您更喜欢int/long id(在url上看起来更好)然后你可以像Chris建议的那样使用findAndModify开始简单的实现一个生成器。当/如果性能/锁定开始成为一个问题,你可以升级你的生成器来实现Hi/Lo算法。这将大大减少'seq'集合的压力。实际上消除了这个问题。(客户端生成器正在使用“池”,并且仅在没有更多空闲ID时才联系DB)
eagi6jfj5#
虽然不支持自动增量,但您可以轻松实现自己的小类来发布增量值。
我自己也需要这个特性,所以我用php写了一个小类。
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,所以它可以避免冲突,但如果用户希望有一个列作为运行序列,他们可以自由地拥有它
ogq8wdun7#
我用的是-mongoose-auto-increment