0

Мне нужно построить Volume-Weighted Average Prive (VWAP) сделок с price_per_unit и quantitiy за определенный промежуток времени.Эластичные поисковые агрегирования: объем-взвешенная Средняя цена

В результате агрегации каждое ведро date_histogram должно содержать VWAP всех сделок, которые произошли до сих пор.

Я не уверен, что это возможно, используя Elasticsearch, а также не то, что было бы правильным путем подойти к нему (например, с помощью скрипта?)?

Основное отображение для trade документа довольно проста:

"trade": { 
    "properties": 
    "trade_id": {"type": "string", "index": "not_analyzed"}, 
    "product_id": {"type": "string", "index": "not_analyzed"}, 
    "quantity": {'type': 'double'}, // number of units 
    "execution_time": {'type': 'date'}, 
    "price_per_unit": {'type': 'double'}, 
    } 
} 

В то время как execution_time следует использовать для date_histogram и общая стоимость торговли является продуктом price_per_unit и quantity. Поэтому VWAP = sum(price_per_unit * quantity)/sum(quantity).

+1

Звучит как [совокупная сумма агрегации] (https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-cumulative-sum-aggregation.html). –

+0

Не могли бы вы придумать образец кода для вопроса сверху? Я попытался найти кумулятивную сумму, но не смог ее реализовать. –

+0

В приведенной ссылке есть образец. И я не могу придумать более качественный образец, чем этот, поскольку вы не предоставили никаких тестовых данных, желаемого вывода и отображений индекса. –

ответ

2
DELETE test 
PUT test 
{ 
    "mappings": { 
    "trade": { 
     "properties": { 
     "trade_id": { 
      "type": "string", 
      "index": "not_analyzed" 
     }, 
     "product_id": { 
      "type": "string", 
      "index": "not_analyzed" 
     }, 
     "quantity": { 
      "type": "double" 
     }, 
     "execution_time": { 
      "type": "date" 
     }, 
     "price_per_unit": { 
      "type": "double" 
     } 
     } 
    } 
    } 
} 

POST test/trade/_bulk 
{"index":{}} 
{"execution_time":"2016-11-18T22:45:27Z","quantity":10,"price_per_unit":5} 
{"index":{}} 
{"execution_time":"2016-11-18T22:45:27Z","quantity":10,"price_per_unit":5} 
{"index":{}} 
{"execution_time":"2016-11-19T22:45:27Z","quantity":10,"price_per_unit":5} 
{"index":{}} 
{"execution_time":"2016-11-20T22:45:27Z","quantity":10,"price_per_unit":5} 
{"index":{}} 
{"execution_time":"2016-11-20T22:45:27Z","quantity":10,"price_per_unit":5} 
{"index":{}} 
{"execution_time":"2016-11-20T22:45:27Z","quantity":10,"price_per_unit":5} 
{"index":{}} 
{"execution_time":"2016-11-21T22:45:27Z","quantity":10,"price_per_unit":5} 
{"index":{}} 
{"execution_time":"2016-11-21T22:45:27Z","quantity":10,"price_per_unit":5} 

POST test/trade/_search 
{ 
    "size": 0, 
    "aggs": { 
    "sales_per_day": { 
     "date_histogram": { 
     "field": "execution_time", 
     "interval": "day" 
     }, 
     "aggs": { 
     "sales": { 
      "sum": { 
      "script": { 
       "lang": "groovy", 
       "inline": "doc['quantity'] * doc['price_per_unit']" 
      } 
      } 
     }, 
     "cumulative_sales": { 
      "cumulative_sum": { 
      "buckets_path": "sales" 
      } 
     } 
     } 
    } 
    } 
} 

И вам необходимо включить inline scripting for groovy.

+0

Спасибо, это было действительно полезно! –