我找不到任何关于此事的博客文章或文档。它们,嵌入式文档和哈希数据类型都非常相似。每个人的利益或限制是什么?
考虑我的架构设计:
class HistoryTracker
include ::Mongoid::Document
include ::Mongoid::Timestamps
field :modifier, type: Hash, default: {}
field :original, type: Hash, default: {}
field :modified, type: Hash, default: {}
field :changeset, type: Hash, default: {}
end
我应该在这个HistoryTracker类中创建几个嵌入式文档吗?或者只是用它?索引怎么样?
答案 0 :(得分:6)
Mongoid在数据库级别以几乎相同的方式存储嵌入式文档和哈希属性。当使用mongoid在模型中声明你的字段时,它是正常的,所以如果你有一个嵌套结构,它就是创建嵌入文档的常态。因为MongoDB是无模式的mongoid需要你声明字段,以便将它们呈现在与ActiveRecord相同的API中。但是对于某些用例,Hash属性为您提供了更多的灵活性。这种灵活性的缺点是您只能使用Hash API,因此您不会获得自动生成的属性方法,也无法以通常在模型类中执行的方式封装业务逻辑。
例如,假设您有一个问卷调查模型,您需要在其中存储包含许多问答对的许多部分。如果系统的关键要求是管理员能够设置新的部分和问题,那么您将无法轻松地将答案建模为包含每个问题的显式字段的常规嵌入式文档。对于那种事情,哈希可能更有意义。
我不知道您的具体要求是什么,但作为一个粗略的指南,我会说当您使用带有嵌入式文档的固定架构棒时,但是当您需要开放式模型时,请考虑Hash属性。< / p>
答案 1 :(得分:1)
使用嵌入式文档,您还可以使用属性别名,如
class Outer
include Mongoid::Document
embeds_one :inner_informative_object_with_long_name, store_as: :inn
end
class Embedded
include Mongoid::Document
attribute :vvla, as: :very_very_long_attribute, type: String
end
所以在数据库中你有短名称(使用的内存少得多),你在代码中使用长名称。
答案 2 :(得分:0)
使用Hashes而不是嵌入式文档遇到的问题
当Mongoid即将序列化文档时,它目前不会查看哈希值的嵌套值并假设它们已经序列化。
所以如果你想要一个&#34;哈希转储&#34;如下
class Event
include Mongoid::Document
field :properties, type: Hash
end
然后你不能在属性中使用对象
class Foo
include Mongoid::DOcument
end
e = Event.new(
properties: {
some_info: Foo.new
}
}
尝试保留以下事件会导致崩溃,因为Foo不会被序列化(尝试e.as_document
并且您会看到some_info
的值不会被序列化)
对问题的引用:Github,MongoDB tracker