Как более эффективно агрегировать эти данные? - PullRequest
2 голосов
/ 27 мая 2011

Я использую 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 голосов
/ 28 мая 2011

Я решил эту проблему с помощью функции MapReduce MongoDB со следующими параметрами:

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;
}

Возвращает один результат MongoDB в том же формате, что и хэш Ruby выше.

...