2019-06-13 16:29:12 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-01-03 17:07:23 +01:00
|
|
|
require 'json'
|
|
|
|
|
2019-06-13 16:29:12 +02:00
|
|
|
# Custom aggregations provides a way to aggregate data in a non-standard way to enhance statistics.
|
|
|
|
# These aggregations will run in ElasticSearch so they must belongs to its syntax.
|
2017-01-03 17:07:23 +01:00
|
|
|
class CustomAggregationService
|
|
|
|
|
|
|
|
##
|
|
|
|
# Run any additional custom aggregations related to the given statistic type, if any
|
|
|
|
##
|
|
|
|
def call(statistic_index, statistic_type, start_date, end_date, custom_query, results)
|
2019-06-13 16:29:12 +02:00
|
|
|
if statistic_type && start_date && end_date
|
2017-01-03 17:07:23 +01:00
|
|
|
stat_index = StatisticIndex.find_by(es_type_key: statistic_index)
|
|
|
|
stat_type = StatisticType.find_by(statistic_index_id: stat_index.id, key: statistic_type)
|
|
|
|
client = Elasticsearch::Model.client
|
|
|
|
stat_type.statistic_custom_aggregations.each do |custom|
|
|
|
|
|
2019-06-13 16:29:12 +02:00
|
|
|
query = sprintf(custom.query, aggs_name: custom.field, start_date: start_date, end_date: end_date)
|
2017-01-03 17:07:23 +01:00
|
|
|
|
2019-06-13 16:29:12 +02:00
|
|
|
if custom_query && !custom_query.empty?
|
2017-01-03 17:07:23 +01:00
|
|
|
# Here, a custom query was provided with the original request (eg: filter by subtype)
|
|
|
|
# so we try to apply this custom filter to the current custom aggregation.
|
|
|
|
#
|
|
|
|
# The requested model mapping (ie. found in StatisticCustomAggregation.es_index > es_type) must have defined
|
|
|
|
# these fields in the indexed json, otherwise the returned value will probably not be what is expected.
|
|
|
|
#
|
|
|
|
# As an implementation exemple, you can take a look at Availability (indexed as fablab/availabilities)
|
|
|
|
# and witch will run custom filters on the fields 'date' and 'subType'. Other custom filters will return 0
|
|
|
|
# as they are not relevant with this kind of custom aggregation.
|
|
|
|
query = JSON.parse(query)
|
|
|
|
custom_query = JSON.parse(custom_query)
|
|
|
|
|
|
|
|
exclude = custom_query.delete('exclude')
|
|
|
|
if exclude
|
2018-06-08 12:27:01 +02:00
|
|
|
query['query']['bool']['must_not'] = [{ term: custom_query['match'] }]
|
2017-01-03 17:07:23 +01:00
|
|
|
else
|
|
|
|
query['query']['bool']['must'].push(custom_query)
|
|
|
|
end
|
|
|
|
query = query.to_json
|
|
|
|
end
|
|
|
|
|
|
|
|
c_res = client.search(index: custom.es_index, type: custom.es_type, body: query)
|
|
|
|
results['aggregations'][custom.field] = c_res['aggregations'][custom.field]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
results
|
|
|
|
end
|
2019-06-13 16:29:12 +02:00
|
|
|
end
|