Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elasticsearch DSL python queries with filters and aggregations on nested properties

I would like to build a filtered Elasticsearch query using filtering via nested objects plus make an aggregation to get the minimum value of a nested object inside a nested objects list.

The filtering part works but I can't bind it with the aggs (aggregations) part. When I add the .aggs.bucket part to my code after the filters it's either being ignored (not visible in the search.to_dict()) or gives me syntax errors.

Can anybody give me an example on how to bind those together? I'm trying to get both the filtered query result end the calculated minimum value from nested1.foo.bar in one response

Example schema:

class MyExample(DocType):
    myexample_id = Integer()
    nested1 = Nested(
        properties={
            'timestamp': Date(),
            'foo': Nested(
                properties={
                    'bar': Float(),
                }
            )
        }
    )
    nested2 = Nested(
        multi=False,
        properties={
            'x': String(),
            'y': String(),
        }
    )

Building the query:

from elasticsearch_dsl import Search, Q

search = Search().filter(
    'nested', path='nested1', inner_hits={},
    query=Q(
        'range', **{
            'nested1.timestamp': {
                'gte': exampleDate1,
                'lte': exampleDate2
            }
        }
    )
).filter(
    'nested', path='nested2', inner_hits={'name': 'x'},
    query=Q(
        'term', **{
            'nested2.x': x
        }
    )
).filter(
    'nested', path='nested2', inner_hits={'name': 'y'},
    query=Q(
        'term', **{
            'nested2.y': y
        }
    )
)

Basically what I need to do is to get the min value for all the nested nested1.foo.bar values for each unique MyExample document (they have unique myexample_id field)

like image 422
user2091046 Avatar asked Oct 18 '22 19:10

user2091046


1 Answers

Adding

search.aggs\
    .bucket('nested1', 'nested', path='nested1')\
    .bucket('nested_foo', 'nested', path='nested1.foo')\
    .metric('min_bar', 'min', field='nested1.foo.bar')

on the next line should do the trick.

like image 144
Honza Král Avatar answered Oct 21 '22 01:10

Honza Král