Module: Hightop::Mongoid
- Defined in:
- lib/hightop/mongoid.rb
Instance Method Summary collapse
-
#top(column, limit = nil, distinct: nil, min: nil, nil: nil) ⇒ Object
super helpful article maximomussini.com/posts/mongoid-aggregation-dsl/.
Instance Method Details
#top(column, limit = nil, distinct: nil, min: nil, nil: nil) ⇒ Object
super helpful article maximomussini.com/posts/mongoid-aggregation-dsl/
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/hightop/mongoid.rb', line 5 def top(column, limit = nil, distinct: nil, min: nil, nil: nil) columns = column.is_a?(Array) ? column : [column] relation = all # terribly named option unless binding.local_variable_get(:nil) columns.each do |c| relation = relation.and(c.ne => nil) end end ids = {} columns.each_with_index do |c, i| ids["c#{i}"] = "$#{c}" end if distinct # group with distinct column first, then group without it # https://stackoverflow.com/questions/24761266/select-group-by-count-and-distinct-count-in-same-mongodb-query/24770233#24770233 distinct_ids = ids.merge("c#{ids.size}" => "$#{distinct}") relation = relation.group(_id: distinct_ids, count: {"$sum" => 1}) ids.each_key do |k| ids[k] = "$_id.#{k}" end end relation = relation.group(_id: ids, count: {"$sum" => 1}) if min relation.pipeline.push("$match" => {"count" => {"$gte" => min}}) end relation = relation.desc(:count) if limit relation = relation.limit(limit) end result = {} collection.aggregate(relation.pipeline).each do |doc| key = doc["_id"].values key = key[0] if key.size == 1 result[key] = doc["count"] end result end |