2013-04-16 183 views
1

當我查詢嵌入式模型時,儘管存在大量包含嵌入式模型實例的父記錄,但沒有記錄被返回。Mongoid嵌入式文檔返回空查詢

有兩種模式,嵌入Band一個Label

class Band 
    include Mongoid::Document 
    embeds_one :label 
end 

class Label 
    include Mongoid::Document 
    field :name, type: String 
    embedded_in :band 
end 

我可以查詢樂隊(Band.allBand.find等)就好了,但是當我查詢標籤,它沒有返回。例如:

創建與嵌入式標籤帶,並將其保存:

> 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.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.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

我錯過了什麼?

回答

2

在mongo中,您的查詢始終以集合爲目標,即可能嵌入其他文檔的完整文檔。對於mongo,它只是一個大的JSON/BSON文檔。現在,Label.allLabel.all相當於查詢Label集合。由於標籤未存儲在Label集合中,所以這些查詢不會返回任何內容。但是,您仍然可以通過調用

Band.where(:'labels._id' => "516cff5a5543d8842e000009") 

或類似

Band.where(:'labels.name' => "rock") 

,如果你想獲得的所有樂隊同一個標籤下這是好的查詢在Band收集標籤。然而,通過這種方式獲得所有標籤非常昂貴並且不推薦。你的主要用例是什麼?如果它顯示樂隊的標籤或獲得具有特定標籤的樂隊,那麼嵌入效果非常好。否則,您可以使用關係(has_many/belongs_to)或完全非規範化,即將標籤保存在波段中並同時保存在單獨的集合中(導致冗餘數據)。

+0

感謝您的明確解釋。我沒有特定的用例,我只是注意到它,並認爲這是一種奇怪的行爲 - 當你對嵌入式Mongoid模型進行查詢時,Mongoid是否不應該至少發出警告? –

+0

@SherwinYu,你是對的,因爲它是不直觀的,即使它是可以理解的。不幸的是,這是Mongoid的許多(不常見)角落的情況,所以要小心:) –

0

我認爲你應該使用has_many,has_one,belongs_to方法來使得像Label.count一樣運行查詢。

當您將文檔嵌入到另一個文檔中時,它將成爲文檔的一部分(序列化屬性)。如果你想選擇標籤,你應該先找到Band,然後檢查標籤屬性。它應該肯定有效。

+0

確定嗎?這似乎不是默認行爲,即使是嵌入式文檔也很不直觀。 –