Forward Advance Learning

Rails Integration with Aggregation (Optional)

We can issue aggregation queries to Mongo using the Mongoid gem. We call Model.aggregate, then pass an array of aggregation operators. For example, say we wanted to perform a simple projection on our kitten to get its name and birth year, we might do this:

Kitten.collection.aggregate([
{ "$project" =>
{
"name" => 1,
"year" => { "$year" => "$birthday"},
}
}
]);

Cursors

This will give us a Cursor object back, which we can interact with, perhaps iterating over it with each:

Kitten.collection.aggregate( [
{ "$project" =>
{
"name"=> true
}
}
]).each do | doc |
puts doc
end

Each time round we'll get a BSON object, which will have the fields we would expect.

Multi stage aggregation

If we wanted to group by year, to get the number of kittens born each year, we could chain a group operator:

Kitten.collection.aggregate([
{"$project" =>
{
"name" => 1,
"year" => { "$year" => "$birthday"},
}
},
{ "$group" =>
{
"_id" => {"year" => "$year"},
"count" => { "$sum" => 1 }
}
}
]);

The syntax is almost identical to the aggregation we have been using in the console.

Exercise - Mongoid Aggregation

Extend your Rails app, or scaffold a new one. Use aggregation and $match to create a controller and view that shows only large.

Optionally Create a model that has a birth date. Create a controller that uses aggregation to group these on date. Create a view that outputs this data, showing the most popular year and month.

Optional Extension

Drop into your rails console. Pick The stocks data. Use $project to format it in a way that a Rails app can understand (lower case keys, no nesting.) Now us the $out: 'collection_name' pipeline stage to output the cleaned data into a new collection. Docs here:

https://docs.mongodb.com/manual/reference/operator/aggregation/out/

No write a Ruby model that can understand the data. Write a Rails controller and view that aggregate the data to show the most popular stocks, based on the data.