9

我找不到任何关于此的博客文章或文档。它们都是嵌入式文档和散列数据类型,非常相似。彼此相比有什么好处或限制?

考虑我的架构设计:

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 类中创建几个嵌入式文档吗?或者只是使用它?索引怎么样?

4

3 回答 3

7

Mongoid 在数据库级别以几乎相同的方式存储嵌入式文档和 Hash 属性。使用 mongoid 在模型中声明字段时这是正常的,因此如果您有嵌套结构,则创建嵌入式文档是正常的。因为 MongoDB 是无模式的 mongoid 需要您声明字段才能以与 ActiveRecord 相同的 API 呈现它们。但对于某些用例,Hash 属性为您提供了更多的灵活性。这种灵活性的缺点是您仅限于 Hash API,因此您无法获得自动生成的属性方法,并且您无法像通常在模型类中那样封装业务逻辑。

例如,假设您有一个问卷模型,您需要在其中存储许多包含许多问答对的部分。如果系统的关键要求是管理员能够设置新的部分和问题,那么您将无法轻松地将答案建模为包含每个问题的明确字段的常规嵌入式文档。对于那种事情,哈希可能更有意义。

我不知道您的具体要求是什么,但作为粗略的指导,我会说,当您使用带有嵌入式文档的固定模式时,但当您需要开放式模型时,请考虑 Hash 属性。

于 2013-03-21T17:30:26.553 回答
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

所以在数据库中你有短名称(使用的内存少得多),你在代码中使用长名称。

于 2013-10-25T06:58:12.620 回答
0

我在使用哈希而不是嵌入文档时遇到的问题

当 Mongoid 即将序列化文档时,它当前不查看哈希的嵌套值并假设它们已经序列化。

所以如果你想有一个像下面这样的“哈希转储”

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不会被序列化)

对问题的引用:GithubMongoDB 跟踪器

于 2017-05-16T20:25:56.150 回答