2016-07-24 89 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'在这里比较好。 –