由服务器生成的pymongo ObjectID

2 投票
2 回答
964 浏览
提问于 2025-04-18 09:04

我正在使用pymongo(一个用于mongodb的Python模块)。

我希望ObjectID能够由服务器自动生成,但似乎当我们不指定时,它是由pymongo自己生成的。

这个问题带来的困扰是,我用ObjectID来按时间排序(就是通过排序_id字段)。但是看起来它是根据每台电脑上设置的时间来生成的,所以我们不能完全依赖这个排序。

有没有什么办法可以解决这个问题呢?

2 个回答

1

我不是Python用户,但我觉得服务器生成_id是行不通的。为了提高性能,_id总是由驱动程序生成,所以当你插入一个文档时,不需要再进行一次查询来获取_id。

有一种可能的方法是生成一个整数序列的_id,就像SqlServer中的IDENTITY ID那样。为了做到这一点,你需要在某个集合中保留一个记录,比如在我的项目中有一个seed,它只有一条记录:

{_id: ObjectId("..."), seqNo: 1 }

关键是,你必须使用findAndModify来确保查找和修改在同一个“事务”中进行。

var idSeed = db.seed.findAndModify({
    query: {},
    sort: {seqNo: 1},
    update: { $inc: { seqNo: 1 } },
    new: false
});
var id = idSeed.seqNo;

这样,你的所有实例就会获得一个唯一的序列号,你可以用它来对记录进行排序。

3

如果你调用 save 方法,并且传入一个没有 _id 字段的文档,你可以通过将一个叫做 manipulate 的选项设置为 False,来强制服务器自己添加 _id 字段,而不是让客户端来添加:

coll.save({'foo': 'bar'}, manipulate=False)

撰写回答