【问题标题】:setting mongoid hash field values设置 mongoid 哈希字段值
【发布时间】:2016-07-19 08:50:15
【问题描述】:

我在 Rails 项目(均为 4.0.x)中使用 Mongoid,并且我有一个包含存储一些无模式数据的哈希字段的文档。

class Thing
  field :name, type: String
  field :mass, type: Integer
  field :info, type: Hash
end

通过此设置,我可以查询具有 :endDate 键的事物,例如:

Thing.where("info.endDate"=>{'$exists'=>true})

这一切都很好,很方便。为这个 :info 字段使用哈希字段很好,因为我要存储的内容没有固定的架构,并且因一件事而异。

好的,但是,我不能对 :info 哈希中的 $set 键/值对使用相同的点语法。 [1]

thing.set("info.endDate"=>Time.now) 

引发Mongoid::Errors::UnknownAttribute 错误。

它告诉我我必须在我的模型中包含Mongoid::Attributes::Dynamic 才能做到这一点,但这对我来说似乎不正确。 The point of the hash field type 似乎允许您使用没有固定架构的数据。我似乎不必包含一个特殊的“动态属性”模块来使用哈希字段。

所以现在,我正在使用常规的旧 [] 语法更新值,然后在模型上调用 save,如下所示:

thing.info[:endDate] = Time.now
thing.save

但很多时候,如果只使用 $set 值会更好。是否有其他语法用于设置哈希字段值?我对上述错误消息和动态属性有误吗?我现在是否坚持对哈希字段进行两步更新?

[1] 诚然,我最近从 mongomapper 迁移过来,因此我对这种语法的期望部分是因为之前在 mongomapper 中能够做到这一点。

【问题讨论】:

  • 我认为定义为 Mongoid::Attributes::Dynamic 的 embeds_one 对你有用(从未测试过这种方法)
  • 我不想要嵌入文档。我想要一个哈希字段,因为我存储在那里的数据因文档而异。 mongoid 给了我一种方法来查询该哈希中的特定键/值对。我希望能够使用 $set 轻松更新该哈希中的键/值对。
  • 不应该是.set(:info => {:endDate => Time.now }) 不过我已经有一段时间没有使用MongoDB了。
  • @AndyGauge 将覆盖整个 :info 字段,而不仅仅是将一个键写入哈希 :-)

标签: ruby-on-rails mongodb mongoid mongoid4


【解决方案1】:

我认为你以错误的方式传递参数。 用逗号替换箭头符号

你可以改成这个,它会起作用的

thing.set("info.endDate", Time.now) 

【讨论】:

  • 谢谢!但这是 Mongoid 3.x 集的语法。从 Mongoid 4.x 开始,他们转而将字段/值对的哈希值传递给 set。
  • 是的@Bee,实际上我在当前项目中使用的是 mongoid 3.x。是的 mongoid 4.x ,将参数设置为键值对。感谢您的回复
【解决方案2】:

哈希字段的作用是,它可以是动态的,只要你想。因此,为了防止您的代码中的错误导致的意外字段污染您的数据库架构,默认情况下禁用此功能。

不,您根本不会对哈希值使用两步更新!

[],[]= 是read_attribute()write_attribute() 的快捷方式,如果不包含Mongoid::Attributes::Dynamic,则应使用。如果您尝试在不启用动态属性的情况下使用$set,您将收到无方法错误,因为它不会将您的动态属性视为已定义的属性。

如果您阅读Mongoid::Attributes::Dynamic 的源代码,您会发现这是添加动态属性功能所必需的。

要通过包含 Mongoid::Attributes::Dynamic 来更新值,您需要执行以下步骤:

thing = Thing.first
thing.set("info.endDate" => Time.now)
thing.reload # This will update the current variable 

否则,如果您需要,您可以轻松跳过此步骤并通过两步法进行值更新

我希望这对您的查询有所帮助。

来源:

Rails mongoid dynamic fields - no method error

Dynamic attributes with Rails and Mongoid

【讨论】:

  • 我仍然对这个答案不满意。关于动态字段的文档似乎是指向文档动态添加字段。当他们谈论动态字段时,似乎在声明的 Hash 字段中设置键/值对并不是他们所指的。不能添加任意键/值对的 Hash 数据类型有什么好处?事实上,我可以向 Hash 添加任意值,只是显然不使用 $set。但也许我只是在这里与 mongoid 的设计争论。我不知道。
  • @Bee 我知道不能在哈希字段上使用$set 似乎令人沮丧。正如我在回答中解释的那样,他们禁用了使用$set 的功能,因为它的值可以是动态的,如果代码中有一些错误,它可能会导致意外的字段。但是当你使用 [],[]= 时,你很确定你使用的是什么值。这就是它的设计方式。但是我们可以通过包含该模块并告诉 Mongoid 我们非常确定我们编写的代码来为哈希字段启用$set。从作者的角度思考,似乎是对的。
  • 太棒了!!完美运行:D
猜你喜欢
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
相关资源
最近更新 更多