Ищите два поля, но оценивайте только один раз в Elasticsearch - PullRequest
1 голос
/ 08 июля 2020

Допустим, у меня есть следующие документы в Elasticsearch:

{
    "display_name": "Jose Cummings",
    "username": "josecummings"
},
{
    "display_name": "Jose Ramirez",
    "username": "elite_gamer"
},
{
    "display_name": "Lance Abrams",
    "username": "abrams1"
},
{
    "display_name": "Steve Smith",
    "username": "josesmose"
}

Я хочу запустить поиск «по мере ввода» для Jose, который выполняет поиск по полям display_name и username , что я могу сделать с помощью этого:

{
    "query": {
        "bool": {
            "must": {
                "multi_match": {
                    "fields": [
                        "display_name",
                        "username"
                    ],
                    "query": "Jose",
                    "type": "bool_prefix",
                    "fuzziness": "AUTO",
                    "boost": 50
                }
            }
        }
    }
}

Проблема здесь в том, что когда я ищу Jose, Хосе Каммингс получает 100 баллов, а Хосе Рамирес и Стив Смит получают только 50 баллов, потому что это кажется суммируйте баллы по двум полям. По сути, это вознаграждает пользователя за то, что он имеет такое же display_name, что и username, чего мы не хотим.

Есть ли способ взять максимальное количество очков только из двух полей? Я пробовал десятки различных комбинаций, используя function_score, boost_mode / score_mode, constant_score, пытаясь выполнить сопоставление should с несколькими запросами match_bool_prefix и т.д. c. Ничего из того, что я пробовал, похоже, не достигает этого.

1 Ответ

1 голос
/ 09 июля 2020

Попробуйте следующее:

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "fields": [
              "display_name^50",
              "username^50"
            ],
            "query": "Jose",
            "type": "bool_prefix",
            "fuzziness": "AUTO",
            "tie_breaker": 0.3
          }
        }
      ]
    }
  }
}

Обратите внимание на эффекты tie_breaker, установленного на 0,0, а не на 0

Также обратите внимание, что ваша оценка bool_prefix

ведет себя как most_fields, но с использованием запроса match_bool_prefix вместо запроса match.

Возможно, вы действительно хотите, чтобы поля имели префикс w / jose. Но если имя пользователя, скажем, cool_jose, оно будет пропущено (если вы, например, не примените не стандартный анализатор ) ...

...