Оценка Elasticsearch на основе соотношения совпадающих токенов

Я играю с Elasticsearch (v 1.7.3, с Java Transport Client) для поиска в базе данных имен людей. Я использую для этого кучу доступных фонетических алгоритмов (DoubleMetaphone, RefinedSoundex и т. Д.), Чтобы проиндексировать поля моего имени и сохранить их. Однако алгоритм оценки, который мне нужен, заключается в том, чтобы вычислить процент близости входного токена к токену в индексе.

Например:

Следующий документ, когда индексируется с использованием фонетических алгоритмов:

{
  "FullName": "Christopher Cruickshank"
}

Расширяется как (выходные данные взяты с использованием API анализа):

{
  "tokens": [
    {
      "token": "C3090360109",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "christopher",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "K3936",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "KRST",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "C3903083",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "cruickshank",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "K3935",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "KRKX",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    }
  ]
}

Теперь во время поиска, когда я запрашиваю:

{
              "match": {
                "FullName": {
                  "query": "Cristopher Krukshank",
                  "boost": 10.0
                }
              }
            }

То, что я хотел бы сделать, это оценить результаты на основе количества совпавших токенов из индекса.

то есть:

(Number of matched tokens per term / Total number of expanded tokens per term) * Boost

Хотя это может работать концептуально, мне интересно, есть ли лучший способ добиться того же.

Кроме того, я склонен продвигать большую часть сложности и логики во время индексации (либо путем хранения количества общих токенов в поле), поэтому моя логика поиска будет проще. Если это разумный подход, то я хотел бы знать, есть ли какие-либо технические последствия использования анализ API в процессе индексации, особенно когда массовая индексация используется для миллионов имен. Я предполагаю, что API Analyze будет вызываться для каждого исходного токена и каждого его расширенного токена (который потенциально может быть огромным!).

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

Другой вариант, о котором я также думаю, - это вызвать api analysis во время запроса и отправить запрос в asticsearch с опцией объяснения, а затем выполнить строковое совпадение в разделе объяснения, чтобы определить, сколько совпадает токенов.

1 ответ

Мы сделали это косвенным путем. Я пытаюсь найти лучший способ и увидел ваш пост.

Решение заключается в том, что при поиске « Кристофер Крукшанк » первое совпадение, например, такое:

« Кристофер Крукшанк младший » с оценкой 10,0 .

Затем вы берете первый результат « Кристофер Крукшанк-младший » и снова ищете его. Конечно первым результатом будет " Кристофер Крукшанк младший ", но с более высоким баллом, например " 20.0 ".

Итак, вы знаете, что максимальный балл равен 20 , тогда для частичного совпадения окончательный балл будет равен « первый балл / максимальный балл », который равен 10/20 = 0,5 . Окончательная оценка будет иметь значение от 0 до 1. 1 означает точное совпадение.

Одна проблема заключается в том, что ввод может быть токеном, который нажимает на что угодно. Например, для «Кристофер Крукшанк XXXXX » XXXXX не может быть токеном в индексе. Поэтому, чтобы сделать это правильно, мы должны использовать количество жетонов для пересчета очков.

Другие вопросы по тегам