我想使用自定义_id生成。以下是我如何使用它。请指导预期的问题。
我在mongo中有一个包含多个文档嵌套的集合。对于我在特定级别插入的每个文档,它都有一个唯一的_id。但是,在不同的层次上,_id可能会重演。 _id也可以为另一个集合重复。
我当前的数据集是<具有2级嵌套的300个文档。 1.我是否会遇到大型数据集的问题? 2.解决问题? 还有别的吗?
答案 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的基本原理的信息,因为您可能正在尝试解决默认实现已解决的问题。希望上面的内容能让您深入了解指导决策的机制。