Skip to content

Instantly share code, notes, and snippets.

@sam-higton
Last active February 3, 2020 10:36
Show Gist options
  • Save sam-higton/727633e8ef651551d3cea8234c85c805 to your computer and use it in GitHub Desktop.
Save sam-higton/727633e8ef651551d3cea8234c85c805 to your computer and use it in GitHub Desktop.
Aggregate service prototype
module AggregateService
def self.aggregate(collection, &block)
agg = Aggregate.new(collection, &block)
agg
end
module AggregateStages
def match(&block)
@stages << {
'$match' => Match.new(&block).formatted
}
end
class Match
def initialize(&constructor)
@field_list = {}
instance_eval(&constructor)
end
def field(key, opts)
@field_list[key] = opts
end
def formatted
@field_list
end
end
def group(key, &block)
@stages << {
'$group' => Group.new(key, &block).formatted
}
end
class Group
def initialize(key, &constructor)
@field_list = {}
@key = key
instance_eval(&constructor)
end
def field(key, opts)
@field_list[key] = opts
end
def formatted
{
"_id" => @key
}.merge(@field_list)
end
end
def add_field
end
class AddField
def initialize(&constructor)
@field_list = {}
instance_eval(&constructor)
end
def field(key, opts)
@field_list[key] = opts
end
end
end
class Aggregate
include AggregateStages
def initialize(collection, &constructor)
@collection = collection
@stages = []
instance_eval(&constructor)
end
def results
@collection.aggregate(@stages)
end
end
end
AggregateService.aggregate(:collection_name) do
match do
field 'sensor_id', eq: 'test'
field 'date', gte: '2010-10-10'
end
add_field do
field 'temp_diff', '$abs' => { '$subtract' => ['$temp', '$ambient_temp'] }
end
group 'sensor_id' do
field 'min_temp', '$max' => '$temp'
field 'max_temp', '$min' => '$temp'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment