1
votes

I store log data in elasticsearch and my records, among other data, contain lists of values. First I represented these lists of values with regular arrays in elastic, but soon realised that the flattening in combination with the inverted index in Lucene made average aggregations on a list such as [1,1,1,1,5] came out completely wrong since the inverted index only contained [1,5]. Clearly avg([1,5]) is different from avg([1,1,1,1,5]).

Seeking out solutions I turned to nested documents, which do not flatten the data.

I now have my nested documents in elasticsearch looking something in the line of:

"nested_documents": [
 { "list1": 1, "list2": 2},
 { "list1": 3, "list2": 4}
]

Using the nested aggregation I am able to do aggregations such as:

 "aggs": {
    "nested_aggregation": {
      "nested": {
        "path": "nested_documents"
      },
      "aggs": {
        "average_of_list1": {
          "avg": {
            "field": "nested_documents.list1"
          }
        }
      }
    }

Which now give me the correct result over the entire data set. However, I do have another requirements as well.

I would like to achieve things like max(avg(nested_documents.list1)), i.e. I want to have the average value of a field of my nested documents. I imagined I could use a script to achieve this, but I can't find a way to access the nested document in scripts. I did achieve the desired result using script and _source, but this was way too slow to be used in production on my datasets.

The only simple (and fast) solution I can imagine is to calculate the averages before storage, and store them along the actual lists, but that doesn't feel right.

1

1 Answers

0
votes

Aggregating over aggregation results are not yet supported in elasticsearch. Apparently there is a concept called reducers that are being developed for 2.0. I would suggest having a look at scripted metric aggregations. Basically, you can create your own aggregation by controlling the collection and computation aspects yourself using scripts.

Have a look at the following question for an example of this aggregation: Elasticsearch: Possible to process aggregation results?