我有一张带有以下结构的痕迹表
id | country_iso | object_id | created_at
每个对象可以包含一个或多个国家/地区的许多条目。我需要弄清楚每个国家现在有多少物体
我不能只按country_iso对它进行分组,因为在这种情况下,我会获得每个国家/地区的条目数,但不包括对象数。
我无法通过country_iso和object_id对其进行分组,因为在这个时间我将获得每个国家/地区中每个对象的条目数。
所以,似乎我必须得到每个对象的最后一个条目,然后按国家分组并获得数量。此外,我需要避免最后一个条目的country_iso等于null的情况。因此,如果object的最后一个条目为null,我们必须在最后一个条目之前获得条目(因此,最新的非null country_iso)。
示例:
1 | US | 1 | 25.02.02
2 | null | 1 | 26.02.02
3 | UK | 2 | 25.02.02
4 | UK | 3 | 25.02.02
5 | UK | 4 | 25.02.02
6 | US | 4 | 26.02.02 `
结果将是
US | 2
UK | 2
提前感谢任何想法 P.S。:请注意,有很多数据(超过10万个对象,每个超过10个条目),并且它位于远程服务器上。所以,我无法获取数据,并以某种方式在主服务器上使用ruby重新计算它们。
答案 0 :(得分:1)
您需要map-reduce或更短的群组版本。
http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Group
http://api.mongodb.org/ruby/current/Mongo/Collection.html#group-instance_method
https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/collection.rb
以下是代码:
MyModel.collection.group(
:key => :country_iso
:initial => { :object_id_set => {} },
:reduce => 'function (obj,prev) { prev.object_id_set[obj.object_id] = 1; }',
:finalize => 'function (final) { final.object_count = keys(final.object_id_set).length }'
)
答案 1 :(得分:0)
MyCollection.where(country_iso: "US").count
答案 2 :(得分:0)
一种不太聪明的方法就是滥用distinct
......
counts = MyModel.distinct(:country_iso).map do |country_iso|
count = MyModel.where(:country_iso => country_iso).distinct(:object_id).count
[country_iso, count]
end
......虽然这是每个国家的1个查询。每次查询可能不会是@ 1ms。