【问题标题】:ObjectID generated by server on pymongopymongo 上的服务器生成的 ObjectID
【发布时间】:2014-06-10 13:27:53
【问题描述】:

我正在使用 pymongo(mongodb 的 python 模块)。

我希望 ObjectID 由服务器自动创建,但是当我们没有指定它时,它似乎是由 pymongo 自己创建的。

它提出的问题是我使用 ObjectID 按时间排序(仅按 _id 字段排序)。但是,它似乎正在使用每台计算机上设置的时间,因此我们不能真正依赖它。 关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: python mongodb pymongo


    【解决方案1】:

    如果您调用 save 并将没有 _id 字段的文档传递给它,您可以通过将(神秘命名的)manipulate 选项设置为 @ 来强制服务器添加 _id 而不是客户端987654328@:

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

    【讨论】:

    • @user3474490 我想缺点是当你使用sharding 时会失败(ObjectId 将由分片服务器生成)。如果您不打算这样做,这绝对比我的解决方案更好。
    • @user3474490 不应该对性能造成任何影响;它只是重新定位生成_id 的点。
    • @yaoxing 根据mongodb doc 看来,这个限制是为了更新和删除。如果我使用插入,分片集群是否还有这个限制?
    • @koushkov 我的意思是,在分片环境中,会有几个不同的mongod 在不同的服务器上工作。 ObjectId 将不再由一台服务器生成,因此您将遇到与现在相同的情况。
    • @yaoxing 好的。我想当我达到那个点时,我可能会实施你的方法
    【解决方案2】:

    我不是 Python 用户,但恐怕无法通过服务器生成 _id。出于性能原因,_id 始终由驱动程序生成,因此当您插入文档时,您无需执行其他查询即可取回 _id。

    这是一种可能的方式,您可以通过生成一个 int 序列 _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;
    

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

    【讨论】:

    • 智能实施!然而,JohnnyHK 的回答似乎限制了获取种子的任何额外查询
    • 只是一个问题,你不应该在 seqNo 上应用你的 $inc 吗?
    • @koushkov 是我的错,应该在seqNo
    猜你喜欢
    • 1970-01-01
    • 2016-05-05
    • 2017-02-03
    • 2019-03-01
    • 2014-08-29
    • 2013-12-08
    • 2013-07-30
    • 2016-09-11
    • 2016-07-24
    相关资源
    最近更新 更多