【问题标题】:Uniqueness of _id column in mongodbmongodb中_id列的唯一性
【发布时间】:2016-05-18 18:00:07
【问题描述】:

我想使用自定义 _id 生成。以下是我的使用方法。请指导预期的问题。

当前实施

我在 mongo 中有一个包含多个文档嵌套的集合。对于我在特定级别插入的每个文档,它都有一个唯一的_id。但是,在不同的级别上,_id 可能会重复。 _id 也可能会在另一个集合中重复。

我当前的数据集是

【问题讨论】:

    标签: java mongodb mongoid mongodb-query


    【解决方案1】:

    好的,简而言之,答案是:是的,您可能会遇到挑战,除非您尝试解决默认设置无法解决的问题,否则不建议您这样做。

    长答案需要简短介绍一下 mongoid 如何实现 _id。

    看这里:

      field(
            :_id,
            default: ->{ BSON::ObjectId.new },
            pre_processed: true,
            type: BSON::ObjectId
          )
    

    其次,mongoid 将身份处理为类和 id 的组合:

        def identity
          [ self.class, self._id ]
        end
    

    现在,BSON::ObjectId.new(BSON here 的规范)创建了一个 12 字节的值,其中包含一个 4 字节的时间戳 (0..3)、一个 3 字节的机器 ID (4..6) 、一个 2 字节的进程 ID (7..8) 和一个 3 字节的计数器 (9..11)。

    > BSON::ObjectId.new.to_bson.length
    => 12
    

    它记录了生成的时间,这很容易知道:

    > BSON::ObjectId.new.generation_time
    => 2016-05-24 05:47:20 UTC
    

    使用 BSON::ObjectId 作为 _id 的基本原理是可索引的好处。由于它是基于时间的,因此在索引中查找基于时间的值很快。它在两个并发线程(不同的进程,不同的机器)中也是唯一的,并且它是自己的(因此在同一进程上的同一秒内操作的 inc 计数器)。由于身份是类和_id的组合,因此这只需要在集合中是唯一的。

    回答您的问题

    从您所写的内容来看,假设您正在将文档相互嵌入。由于嵌入文档只能从实际文档中搜索,并且嵌入文档有自己的类,因此 _id 只需要在该类中是唯一的。

    例子:

    class A
      include Mongoid::Document
      embeds_many :b
      embeds_many :c, class_name: 'B'
    end 
    
    class B
      include Mongoid::Document
      embedded_in :a
    end
    
    >obj = A.create
    => #<A _id: 5743f10b0da757b22a1cfa69, >
    
    > obj.b << B.new
    => [#<B _id: 5743f12f0da757b22a1cfa6a, >]
    
    > obj.as_document
    => {"_id"=>BSON::ObjectId('5743f10b0da757b22a1cfa69'), "b"=>[{"_id"=>BSON::ObjectId('5743f12f0da757b22a1cfa6a')}]}
    
    > A.find_by('b._id' => BSON::ObjectId('5743f12f0da757b22a1cfa6a'))
    => #<A _id: 5743f10b0da757b22a1cfa69, >
    
    >obj.c << B.new
    => [#<B _id: 5743f2590da757b22a1cfa6b, >]
    
    > obj.as_document
    => {"_id"=>BSON::ObjectId('5743f10b0da757b22a1cfa69'), "b"=>[{"_id"=>BSON::ObjectId('5743f12f0da757b22a1cfa6a')}], "c"=>[{"_id"=>BSON::ObjectId('5743f2590da757b22a1cfa6b')}]}
    

    从上面可以看出,您可以使用 _id 的 mongoid 实现跨嵌入式文档进行稳健的搜索、存储和查找。由于 BSON::ObjectId 即使在嵌入式文档中也是当时唯一的,所以我们(社区)需要有关您自定义 _id 的基本原理的信息,因为您可能正在尝试解决默认实现已经解决的问题。希望以上内容能让您深入了解指导您决策的机制。

    【讨论】:

    • 谢谢,这是一个非常全面的答案。但是,要回答您的问题,没有具体说明为什么会这样。
    猜你喜欢
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多