Агрегация DSL Pythonasticsearch DSL / метрика вложенных значений на документ

1

Я пытаюсь найти минимальное (наименьшее) значение в двухуровневой вложенности (отдельное минимальное значение для каждого документа).

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

Схема моего примера:

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(),
        }
    )

И вот как я ищу и агрегирую:

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
        }
    )
)

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

В основном мне нужно получить минимальное значение для всех вложенных значений nested1.foo.bar для каждого уникального MyExample (у них есть уникальное поле myexample_id)

Теги:
elasticsearch
elasticsearch-dsl

1 ответ

2
Лучший ответ

Если вы хотите минимальное значение для каждого документа, тогда поместите все ведра nested в агрегирование ковша terms в поле myexample_id:

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

Обратите внимание, что это агрегирование может быть чрезвычайно дорогостоящим для вычисления, поскольку оно должно создавать ведро для каждого документа. Для такого использования может быть проще вычислить минимум на основе документа как script_field или в приложении.

  • 1
    Я даже собирался предложить, чтобы это минимальное значение было вычислено во время индексации и сохранено на корневом уровне документа. Это сделало бы все это намного более производительным, чем несколько уровней агг во nested документах или с использованием сценариев.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню