Как выбрать верхние сегменты терминов на основе функции восстановления в Elasticsearch - PullRequest
0 голосов
/ 07 сентября 2018

Рассмотрим следующий запрос для Elasticsearch 5.6:

{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "rescore": [
    {
      "window_size": 10000,
      "query": {
        "rescore_query": {
          "function_score": {
            "boost_mode": "replace",
            "script_score": {
              "script": {
                "source": "doc['topic_score'].value"
              }
            }
          }
        },
        "query_weight": 0,
        "rescore_query_weight": 1
      }
    }
  ],
  "aggs": {
    "distinct": {
      "terms": {
        "field": "identical_id",
        "order": {
          "top_score": "desc"
        }
      },
      "aggs": {
        "best_unique_result": {
          "top_hits": {
            "size": 1
          }
        },
        "top_score": {
          "max": {
            "script": {
              "inline": "_score"
            }
          }
        }
      }
    }
  }
}

Это упрощенная версия, в которой реальный запрос содержит более сложный основной запрос, а функция восстановления гораздо более интенсивна.

Позвольте мне сначала объяснить его цель, если я собираюсь потратить 1000 часов на разработку ручки, которая пишет в пространстве, когда карандаш действительно решит мою проблему. Я выполняю быстрый начальный запрос, затем восстанавливаю верхние результаты с помощью гораздо более интенсивной функции. Из этих результатов я хочу показать самые верхние значения, т. Е. Два результата не должны иметь одинаковые значения identical_id. Если есть лучший способ сделать это, я бы тоже счел это ответом.

Я ожидал, что запрос, подобный этому, упорядочит результаты по запросу rescore, сгруппирует все результаты, которые имели одинаковый identical_id, и отобразит самый высокий рейтинг для каждой такой отдельной группы. Я также предположил, что, поскольку я упорядочиваю эти группы агрегации терминов по максимальному родительскому элементу _score, они должны будут отображать наилучший результат, который они содержат, как определено из исходного запроса на восстановление.

Реальность такова, что сегменты терминов упорядочены по максимальному количеству запросов, а не по количеству запросов для повторных запросов. Странно, но верхние попадания в ведрах, кажется, используют спасение.

Есть ли лучший способ достичь желаемого конечного результата или каким-то образом можно исправить этот запрос, чтобы он работал так, как я этого ожидаю?

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

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

{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggs": {
    "sample": {
      "sampler": {
        "shard_size": 10000
      },
      "aggs": {
        "distinct": {
          "terms": {
            "field": "identical_id",
            "order": {
              "top_score": "desc"
            }
          },
          "aggs": {
            "best_unique_result": {
              "top_hits": {
                "size": 1,
                "sort": [
                  {
                    "_script": {
                      "type": "number",
                      "script": {
                        "source": "doc['topic_score'].value"
                      },
                      "order": "desc"
                    }
                  }
                ]
              }
            },
            "top_score": {
              "max": {
                "script": {
                  "source": "doc['topic_score'].value"
                }
              }
            }
          }
        }
      }
    }
  }
}

Агрегация sampler будет принимать N первых попаданий на шард из основного запроса и выполнять агрегацию по ним. Затем в максимальном агрегаторе, который определяет порядок сегментов, я использую тот же сценарий, что и тот, который я использую, чтобы выбрать лучший удар из сегмента. Теперь сегменты и верхние попадания выполняются над одинаковыми верхними N наборами элементов, и сегменты будут упорядочены по максимальному количеству одинаковых баллов, сгенерированных из одного и того же сценария. К сожалению, мне все еще нужно запустить скрипт один раз, чтобы упорядочить сегменты, и один раз, чтобы выбрать верхний попадание в пределах сегмента, и вы могли бы вместо этого использовать rescore для упорядочивания верхних попаданий, но в любом случае он должен выполняться дважды, и я обнаружил, что он быстрее как сценарий сортировки, а затем как rescore

0 голосов
/ 07 сентября 2018

Из документации :

Средство восстановления запросов выполняет второй запрос только для результатов Top-K , возвращаемых фазами запроса и post_filter . Количество документов, которые будут проверены на каждом осколке, может контролироваться параметром window_size, который по умолчанию равен 10.

Когда rescore query вступает в силу после фазы post_filter, я предполагаю, что блоки агрегации термина уже зафиксированы.

Понятия не имею, как можно объединить восстановление и объединение. Извините: (

...