当我查询嵌入式模型时,尽管有大量父记录包含嵌入式模型的实例,但不会返回任何记录。
有两种型号,Label
中嵌入Band
:
class Band
include Mongoid::Document
embeds_one :label
end
class Label
include Mongoid::Document
field :name, type: String
embedded_in :band
end
我可以查询Band(Band.all
,Band.find
等),但是当我查询Label时,它什么都不返回。例如:
我创建了带有嵌入标签的乐队,并将其保存:
> b = Band.create
=> #<Band _id: 516cff525543d8842e000008, _type: nil>
> b.build_label name: "new label"
=> #<Label _id: 516cff5a5543d8842e000009, _type: nil, name: "new label">
> b.save
=> true
然后我查询Band模型,一切都很好:
> Band.all.to_a
=> [#<Band _id: 516cff525543d8842e000008, _type: nil>]
> Band.count
=> 1
> Band.first.label
=> #<Label _id: 516cff5a5543d8842e000009, _type: nil, name: "new label">
> Band.find "516cff525543d8842e000008"
=> #<Band _id: 516cff525543d8842e000008, _type: nil>
但是当我查询Label模型时,什么都没有出现!
> Label.all.to_a
=> []
> Label.count
=> 0
> Label.last
=> nil
> Label.first
=> nil
> Label.find "516cff5a5543d8842e000009" # this is the label id from Band
=> nil
我几乎肯定这不是预期的行为。代码直接来自Mongoid文档中的示例:http://mongoid.org/en/mongoid/docs/relations.html#embeds_one
我错过了什么?
答案 0 :(得分:2)
在mongo中,您的查询始终以集合为目标,即可能嵌入其他文档的完整文档。对于mongo来说,它只是一个大的JSON / BSON文档。现在,Label.all
或Label.all
等同于查询Label
集合。由于标签未存储在Label
集合中,因此这些查询不会返回任何内容。但是,您仍然可以通过调用
Band
集合上的标签
Band.where(:'labels._id' => "516cff5a5543d8842e000009")
或类似
Band.where(:'labels.name' => "rock")
如果您希望获得具有特定标签的所有乐队,这很好。然而,以这种方式获得所有标签是非常昂贵的,不推荐。你的主要用例是什么?如果它显示乐队的标签或获得带有特定标签的乐队,那么嵌入很棒。否则,您可以完全使用关系(has_many / belongs_to)或非规范化,即同时在标签内和单独的集合中保存标签(导致冗余数据)。
答案 1 :(得分:0)
我认为您应该使用has_many,has_one,belongs_to方法,以便像Label.count一样运行查询。
当您将文档嵌入到另一个文档中时,它将成为文档的一部分(序列化属性)。如果要选择标签,首先应找到Band,然后检查label属性。它应该肯定有用。