Rails - Mongoid 查询关联字段

Rails - Mongoid querying on a association field

我有这样的模型

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中存在多条满足条件的记录,上述查询结果集为空。谁能指出我可能做错了什么。

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

当你说:

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

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