I have data in the following form in Elasticsearch:
[
{
"id": 1,
"name": "abc",
"score": 10,
"values": [
{
"v1": 1,
"v2": 2
}
]
},
{
"id": 2,
"name": "def",
"score": 20,
"values": [
{
"v1": 3,
"v2": 4
}
]
}
]
Currently, I am calculating average on score
using the following code:
s = Search(using=es, index=index).query(Q(query))
s.aggs.bucket('average_score', 'avg', field='score') # average_score = 15
Now I wish to compute average on v1
and v2
using elasticsearch_dsl
but I don't know how to do nested aggregation. In this example, v1 = 2
and v2 = 3
. Please help. Thanks in advance!
Edit: Unfortunately, here values
is an object instead of nested.
No idea how to do it in your DSL but here are the raw steps.
Mapping:
PUT avgs/
{
"mappings": {
"properties": {
"values": {
"type": "nested",
"properties": {
"v1": {
"type": "integer"
},
"v2": {
"type": "integer"
}
}
}
}
}
}
Indexing:
POST avgs/_doc
{
"id": 1,
"name": "abc",
"score": 10,
"values": [
{
"v1": 1,
"v2": 2
}
]
}
POST avgs/_doc
{
"id": 2,
"name": "def",
"score": 20,
"values": [
{
"v1": 3,
"v2": 4
}
]
}
Querying:
GET avgs/_search
{
"size": 0,
"aggs": {
"avg_v1": {
"nested": {
"path": "values"
},
"aggs": {
"nested_v1": {
"avg": {
"field": "values.v1"
}
}
}
},
"avg_v2": {
"nested": {
"path": "values"
},
"aggs": {
"nested_v2": {
"avg": {
"field": "values.v2"
}
}
}
}
}
}
Yielding:
...
"aggregations" : {
"avg_v2" : {
"doc_count" : 2,
"nested_v2" : {
"value" : 3.0
}
},
"avg_v1" : {
"doc_count" : 2,
"nested_v1" : {
"value" : 2.0
}
}
}
...