mongodb中_id列的唯一性

时间:2016-05-18 18:00:08

标签: java mongodb mongoid mongodb-query

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

当前实施

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

我当前的数据集是<具有2级嵌套的300个文档。 1.我是否会遇到大型数据集的问题? 2.解决问题? 还有别的吗?

1 个答案:

答案 0 :(得分:0)

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

长答案需要简短介绍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的基本原理的信息,因为您可能正在尝试解决默认实现已解决的问题。希望上面的内容能让您深入了解指导决策的机制。