2016-07-24 205 views
0

我有模特這樣導軌 - Mongoid查詢在關聯領域

class TestOne 
    field value 

    belongs_to test_two ,:class_name => 'TestTwo' 
end 

class TestTwo 
    field name 
    field start_time, :type => DateTime 

    has_many TestOne 

end 

I am running a query of range like this 

result = TestOne.where(:value => "some_value" , 'test_two.start_time' => (Time.now-1.days..Time.now + 1.days).last 

的結果集上面的查詢是空的,即使存在着TestOne多家唱片是符合標準。任何人都可以提出我可能做錯了什麼。

回答

2

MongoDB查詢一次只能訪問一個集合,這裏沒有連接。

當你說:

'test_two.start_time' => (...) 

的MongoDB將尋找一個名爲test_twotest_ones一個字段是一個散列(或散列數組)與哈希內start_time場。你沒有這個結構,所以你的查詢沒有找到任何東西。此外,您可以查詢任何您喜歡的字段並且MongoDB不會投訴的任何MongoDB集合;集合中的文檔沒有設置每個集合結構:任何集合中的任何文檔都可以包含任何類型的任何字段。這就是爲什麼你可以使用這個查詢沒有任何人抱怨。

你需要做的查詢分兩步(即做手工加入):

test_two_ids = TestTwo.where(:start_time => (Time.now-1.days..Time.now + 1.days)).pluck(:id) 
result = TestOne.where(:value => "some_value" , :test_two_id.in => test_two_ids).last 

有一對夫婦的選擇是更多的工作:

  1. 保持db.test_twos.start_time副本在db.test_ones集合中(即通過非規範化預先計算JOIN)。這需要您每次更新db.test_twos.start_time更改副本,並且您必須定期檢查所有副本並修復損壞的副本,因爲它們會不同步。
  2. 如果你不需要TestTwo自己存在,然後在TestOne內嵌入TestTwo。這會讓你在你的db.test_ones集合中有一個叫做test_two的散列字段,你的原始查詢可以工作。但是,您將無法自行訪問TestTwo,您必須通過TestOne
+1

使用'pluck(:id)'而不是'.only(:id).map(&:id)' –

+0

@ CyrilDuchon-Doris你是對的,'pluck'在這裏比較好。 –