就像在MYSQL中一样,我想要一个递增的ID。
答案 0 :(得分:18)
您需要使用MongoDB的findAndModify命令。有了它,你可以atomically select and increment a field。
db.seq.findAndModify({
query: {"_id": "users"},
update: {$inc: {"seq":1}},
new: true
});
这会增加users
集合的计数器,然后您可以在插入之前将其添加到文档中。由于它是原子的,因此您不必担心会导致ID冲突的竞争条件。
它不像MySQL的auto_increment
标志那样无缝,但您通常也可以选择在Mongo驱动程序中指定自己的ID工厂,这样就可以实现一个使用findAndModify来透明地递增和返回ID的工厂,导致更像MySQL的体验。
这种方法的缺点是,因为每个插入都依赖于序列集合上的写锁定,如果你正在进行大量写操作,那么你可能会很快就会出现瓶颈问题。如果您只是想保证集合中的文档按插入顺序排序,请查看Capped Collections。
答案 1 :(得分:13)
MongoDB旨在水平扩展。在这种情况下,自动增量会导致id冲突。这就是为什么id看起来更像guid / uuid。
答案 2 :(得分:2)
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。 INSERT DOC
db.users.insert({
_id: getNextSequence("USER"),
name: "Nishchit."
})
在此模式中,乐观循环计算递增的_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。 INSERT DOC
var myCollection = db.USERS;
insertDocument(
{
name: "Nishchit Dhanani"
},
myCollection
);
来自 MongoDB的官方文档。
答案 3 :(得分:1)
如果您怀疑您的数据可能跨越多个服务器(也称为分片),那么请使用Dennis并使用本机ObjectId。
如果您更喜欢int / long id(在url上看起来更好),那么您可以使用Chris建议的findAndModify开始使用生成器的天真实现。 当/如果性能/锁定开始成为问题,您可以升级您的发电机以实现Hi / Lo算法。这将减少'seq'系列的压力。并实际上消除了这个问题。 (客户端生成器使用'池',只有在没有更多空闲ID时才与DB联系)
答案 4 :(得分:0)
虽然不支持自动增量,但您可以轻松实现自己的小类来发布增量值。
我自己需要这个功能,所以我在php中编写了一个小类。我在我的博客上写了这篇文章,take a look here
答案 5 :(得分:0)
@TIMEX:检查以下链接是否可以帮助您,如果您正在寻找序列号而不是ID(coz ID由mongo保留)
@Dennis Burton 如果用户自动增加它不会导致碰撞?我觉得,因此mongo db使用自己的_Id,因此它可以避免碰撞,但如果用户希望有一个列作为运行序列,他们可以自由地使用它
答案 6 :(得分:0)
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);