1

我有一个具有以下结构的跟踪表
id | country_iso | object_id | created_at
每个对象可以有一个或多个国家的许多条目。我需要弄清楚每个国家/地区现在有多少物品。
我不能只按 country_iso 对它进行分组,因为在这种情况下,我将获得每个国家/地区的条目数,而不是对象数。
我不能按 country_iso 和 object_id 对其进行分组,因为此时我将获得每个国家/地区每个对象的条目数。

所以,似乎我必须为每个对象获取最后一个条目,然后按国家/地区对它们进行分组并获取数量。我还需要避免最后一个条目的 country_iso 等于 null 的情况。因此,如果 object 的最后一个条目为 null,我们必须在 last 之前获取条目等一个(因此,最新的不为 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

提前感谢您的任何想法。
PS:请注意,有很多数据(超过 100 000 个对象,每个对象超过 10 个条目)并且位于远程服务器上。因此,我无法获取数据并以某种方式在主服务器上使用 ruby​​ 重新计算它们。

4

3 回答 3

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 }'
)
于 2012-05-18T03:07:30.233 回答
0
MyCollection.where(country_iso: "US").count
于 2012-05-17T20:06:35.057 回答
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 个查询。每次查询 1 毫秒可能并不可怕。

于 2012-05-18T03:15:00.013 回答