Найдите один результат на основе запроса термина или список результатов на основе запроса соответствия - PullRequest
1 голос
/ 17 июня 2020

У меня есть указатель документов, каждый из которых содержит поля id и name. Каждый документ name уникален.

Я хочу выполнить запрос к полю name, который возвращает один точный результат, если это возможно, или возвращается, чтобы вернуть список похожих результатов. Например, если поисковый запрос - Acme Incorporated и есть точный результат, верните только его. В противном случае вернуть похожие совпадения; например: ACME In c. , acme , Ace et c.

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

{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "name.exact": "Acme Incorporated"
          }
        },
        {
          "match": {
            "name": "Acme Incorporated"
          }
        }
      ]
    }
  }
}

Это возвращает список похожих совпадений И точное совпадение, если оно есть, потому что хотя бы один запрос должен быть успешным. Это явно неверно.

Чтобы упростить приведенный выше запрос терминов на основе ключевых слов, я добавил name.exact к моему сопоставлению документов:

{
  "mappings": {
    "properties": {
      "id": {
        "type": "integer"
      },
      "name": {
        "type": "text",
        "fields": {
          "exact": { 
            "type":  "keyword"
          }
        }
      }
    }
  }
}

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

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

Edit

В настоящее время я думаю, что I go с запросом Multi Search, как описано выше, первым является тот же запрос на основе ключевых слов, чтобы попытаться найти точный результат и второй - составной запрос bool, исключающий точный результат.

{
  "query": {
    "bool": {
      "must": {
        "match": {
          "name": "Acme Incorporated"
        }
      },
      "must_not": {
        "term": {
          "name.keyword": "Acme Incorporated"
        }
      }
    }
  }
}

1 Ответ

0 голосов
/ 19 июня 2020

В конце концов, MultiSearch API подходит для моего варианта использования:

Multi Search API выполняет несколько поисков из одного запроса API. Формат запроса аналогичен формату массового API и использует формат с разделителями новой строки JSON (ND JSON).

Я использовал это для выполнения двух запросов в одном запросе:

  1. Найдите любые точные результаты с помощью запроса term на основе ключевых слов в поле документа name.
  2. Найдите любые похожие результаты с помощью запроса bool, содержащего match запрос к полю документа name и must_not первого запроса для фильтрации любых точных результатов.

Тело множественного поиска состоит из одной или нескольких пар символов ( необязательно) пустой заголовок и тело (один запрос), разделенные символами новой строки; например:

GET /myindex/_msearch
{}
{"query": {"constant_score": {"filter": {"term": {"name.keyword": "Acme Incorporated"}}}}}
{}
{"query": {"bool": {"must": {"match": {"name": "Acme Incorporated"}}, "must_not": {"term": {"name.keyword": "Acme Incorporated"}}}}}

Запрос имеет формат nd json, в котором указано, что «Каждая строка является допустимым JSON значением». Для этого необходимо, чтобы каждый запрос был сжат до одной строки, что не очень удобно для чтения, но не проблема, если вы используете библиотеку для создания запросов.

...