Rails - 在关联字段上查询Mongoid

时间:2016-07-24 15:48:32

标签: ruby-on-rails 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中存在满足条件的多条记录,上述查询的结果集也为空。任何人都可以提出我可能做错的事情。

1 个答案:

答案 0 :(得分:2)

MongoDB查询一次只能访问一个集合,此处没有连接。

当你说:

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

MongoDB将在名为test_ones的{​​{1}}中查找一个字段,该字段是散列(或哈希数组),该哈希值中包含test_two字段。您没有这种结构,因此您的查询无法找到任何内容。

此外,您可以查询任何MongoDB集合,查找您喜欢的任何字段,MongoDB不会抱怨;集合中的文档没有设置每个集合结构:任何集合中的任何文档都可以包含任何类型的任何字段。这就是为什么你可以在没有人抱怨的情况下使用这个查询的原因。

您需要分两步执行查询(即手动连接):

start_time

还有一些替代方案更有效:

  1. 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 集合中保留db.test_twos.start_time的副本(即通过非规范化预先计算JOIN)。这需要您每次db.test_ones更改时更新副本,并且您必须定期检查所有副本并修复损坏的副本,因为它们将不同步。
  2. 如果您不需要db.test_twos.start_time独立存在,请在TestTwo内嵌入TestTwo。这将为您留下TestOne集合中名为test_two的哈希字段,并且您的原始查询将起作用。但是,您将无法再自行访问db.test_ones,您必须通过TestTwo