我有一种情况,我需要从 mongo 返回一个对象集合,但需要使用两个查询来获取结果。这些结果的顺序很重要,因为它们是分页的。
这是第一个查询:(基于类别和价格范围的列表)
my_listings = MoListing.where(criteria_a)
第二个查询需要使用第一个查询的结果作为过滤器。所以像:
everything_else = MoListing.where(criteria_b)
然后合并结果:
my_listings << everything_else
最后,返回分页结果:
my_listings.page(1).per(25)
似乎我的部分问题是 mongo 查询在需要之前不会执行。有没有办法让我在给定点触发查询的执行?或者在构建这个结果集时我应该采取另一种方法吗?
更新更多信息
我看到的行为是返回的只是listings
. 我还确认everything_else
确实包含预期的记录(my_listings 中有 48 条记录,everything_else 中有 52 条记录)。
.all
如评论中提到的那样应用我的查询时,不会产生任何影响。puts listings.inspect
结果在
10:57:00 web.1 | #<Mongoid::Criteria
10:57:00 web.1 | selector: {"price"=>{"$gte"=>25, "$lte"=>75}},
10:57:00 web.1 | options: {},
10:57:00 web.1 | class: MoListing,
10:57:00 web.1 | embedded: false>
但是,listings.count
确实会导致48
. 我只是错过了一些合并这些结果的愚蠢简单方法吗?一旦我在一个集合中得到结果,这将如何影响随后的分页功能。我kaminari
用于分页。
更新 2
根据下面的答案和我自己的反复试验,我发现 to_a 是一个解决方案,但不是一个理想的解决方案。这确实起作用:
#merge the results together as an Array
results = (listings.to_a | everything_else.to_a)
这导致通过 Kaminari 的分页必须更改,因为我们不再使用 mongo 标准,而是使用标准数组。这是新的分页方法:
Kaminari.paginate_array(results).page(page).per(per_page)
使用包含 100 条记录的小型数据集,这很好而且花花公子 - 54 毫秒
"debug":{"success":true,"pre_render_duration":54.808775999999995,"overall_duration":86.36554100000001,"count":25},"pagination":{"total_pages":4,"current_page":1}}
但是,使用更大的数据集时,使用 .to_a 方法组合这些数据时,我发现时间明显变慢。尽管这些示例并不完全是苹果对苹果,但如此大的差异表明 to_a 返回所有内容的问题,迫使 Kaminari 使用更多的实际数据:
我没有 to_a 的结果,只返回应用了标准的所有记录 - 15ms
"debug":{"success":true,"pre_render_duration":15.107164,"overall_duration":18.267599,"count":25},"pagination":{"total_pages":81,"current_page":1}}
我的结果与 to_a,合并两个结果集 - 415ms
"debug":{"success":true,"pre_render_duration":415.258199,"overall_duration":450.66537800000003,"count":25},"pagination":{"total_pages":81,"current_page":1}}
总而言之,这不是一个有效的选择。即使使用大型数据集,单独返回每个数据集也需要 <15ms,所以我认为我需要完成的是一种将条件合并在一起的方法,以便针对 Mongo 运行单个查询,从而允许在 db 上发生分页,它应该是。
在 SQL 中,我会做一些大致类似的事情
select
*
from
listings
where
field = "blah"
union all
select
*
from
listings
where
field <> "blah"
是否可以在 Mongo 中执行此操作?