I am using Rail 3 with Mongoid as my ODM.
I have imported the following documents into 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" }
The following code produces a nested hash of sorted distinct values:
@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
The resulting hash looks like this:
{
"Make A" => {
"Model 1" => ["Variant 1"],
"Model 2" => ["Variant 1", "Variant 2"]
},
"Make B" => {
"Model 3" => ["Variant 1"]
}
}
This all works fine, but is very inefficient as it involves so many queries. Is there a better way of achieving this, perhaps by having MongoDB perform the aggregation?
I solved this using MongoDB’s MapReduce function with the following paramaters:
This returns a single MongoDB result in the same format as the Ruby hash above.