Поиск по именам: повышение релевантности для приближенных совпадений в многозначном поле - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь заставить поле имен работать в Elasticsearch разумно, и мне трудно найти руководство.Пожалуйста, помогите мне, Интернет!

Мои документы имеют несколько авторов, и поэтому поле многозначного имени.Допустим, у меня есть поиск по paul f tompkins и два документа: {"authors": ["Paul Tompkins", "Dietrich Kohl"]} и {"authors": ["Paul Wang", "Darlene Tompkins"]}.

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

Как я могу это сделать?Два метода, которые я знаю для повышения близости - это дранка (которая, как я полагаю, будет генерировать дранку paul_f и f_tompkins, ни одна из которых не совпадает) и запрос фразы с откатом (который не будет выполнен из-за токена fне существует).

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

(Мне не помогло бы иметь клиентскую логику, которая пытается убрать f из запроса - это упрощенный пример, но предположим, что я также хочу иметь возможность обрабатывать запросы, такие как paul francis tompkins или paul f tompkins there will be blood.)

1 Ответ

0 голосов
/ 23 ноября 2018

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

"mappings": {
  "_doc": {
    "properties": {
      "authors": {
        "type": "nested",
        "properties": {
          "name": {
            "type": "text",
            "fields": {
              "raw": {
                "type": "keyword"
              }
            }
          }
        }
      }
    }
  }
}

Примечание : Подполе raw может бытьиспользуется для некоторых других сценариев и не имеет отношения к решению.

Теперь давайте индексировать документы, как показано ниже:

Документ 1:

{
  "authors": [
    {
      "name": "Paul Tompkins"
    },
    {
      "name": "Dietrich Kohl"
    }
  ]
}

Документ 2:

{
  "authors": [
    {
      "name": "Paul Wang"
    },
    {
      "name": "Darlene Tompkins"
    }
  ]
}

Позволяет запросить их следующим образом:

{
  "explain": true,
  "query": {
    "nested": {
      "path": "authors",
      "query": {
        "query_string": {
          "query": "paul l tompkins",
          "fields": [
            "authors.name"
          ]
        }
      }
    }
  }
}

Результат:

  "hits": {
    "total": 2,
    "max_score": 1.3862944,
    "hits": [
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.3862944,
        "_source": {
          "authors": [
            {
              "name": "Paul Tompkins"
            },
            {
              "name": "Dietrich Kohl"
            }
          ]
        }
      },
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.6931472,
        "_source": {
          "authors": [
            {
              "name": "Paul Wang"
            },
            {
              "name": "Darlene Tompkins"
            }
          ]
        }
      }
    ]
  }

ПРИМЕЧАНИЕ. В запросе, который я также использовал объяснение:правда .Это дает объяснение расчета баллов (я не включил вывод объяснения выше, так как он очень длинный. Вы можете попробовать его).

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

{
  "name": "Paul Tompkins"
}

, будет иметь более высокий балл, поскольку оба термина paul и tompkins находятся в одном и том же дочернем документе.

В случае массива все имена принадлежат одному и тому же полю, а не отдельным дочерним документам и, следовательно, разнице.

Таким образом, мы можем достичь желаемого результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...