如何更有效地汇总这些数据?

时间:2011-05-26 21:38:24

标签: ruby-on-rails ruby ruby-on-rails-3 mongodb mongoid

我使用Rail 3和Mongoid作为我的ODM。

我已将以下文档导入MongoDB:

{ "make" : "Make A", "model": "Model 1", "variant" : "Variant 1" }
{ "make" : "Make B", "model": "Model 3", "variant" : "Variant 1" }
{ "make" : "Make A", "model": "Model 2", "variant" : "Variant 2" }
{ "make" : "Make A", "model": "Model 2", "variant" : "Variant 1" }

以下代码生成已排序的不同值的嵌套哈希:

@makes = Item.all.distinct(:make).sort

@models = {}
@makes.each do |make|
  @models[make] = Item.where(:make => make).distinct(:model).sort
end

@output = {}
@models.each_pair do |make, models|
  @output[make] = {}
  models.each do |model|
    @output[make][model] = Item.where(:make => make, :model => model).distinct(:variant).sort
  end
end

结果哈希看起来像这样:

{
  "Make A" => {
    "Model 1" => ["Variant 1"],
    "Model 2" => ["Variant 1", "Variant 2"]
  },
  "Make B" => {
      "Model 3" => ["Variant 1"]
  }
}

这一切都很好,但效率很低,因为它涉及很多查询。有没有更好的方法来实现这一点,可能是让MongoDB执行聚合?

1 个答案:

答案 0 :(得分:0)

我使用MongoDB MapReduce函数使用以下参数解决了这个问题:

map = function() { 
  emit( 1, { make: this.make, model: this.model, variant: this.variant } ); 
}

reduce = function(key, values) {
  var result = {};
  values.forEach(function(value) {
    if (!result[value.make]) result[value.make] = {};
    if (!result[value.make][value.model]) result[value.make][value.model] = [];
    result[value.make][value.model].push(value.variant);
  });
  return result;
}

这将以与上面的Ruby哈希相同的格式返回单个MongoDB结果。