Автозаполнение соответствия в Elastic Search

search elasticsearch autocomplete full-text-search search-engine

508 просмотра

1 ответ

Итак, у меня есть identifierстроковое поле в упругом поиске, которое содержит такие значения, как D123, M1и T23т. Д.

Я пытаюсь построить автозаполнения в поисках этой области , такие , что запрос о D12может соответствовать D12, D120, D121, ..., и D1210т.д.

В настоящее время я создал собственный фильтр и анализатор ребер ngram так:

"filter": {
  "autocomplete_filter": {
    "type": "edgeNGram",
    "min_gram": 2,
    "max_gram": 10
  }
}

"analyzer": {
  "autocomplete": {
      "type": "custom",
      "tokenizer": "whitespace",
      "filter": {"lowercase", "autocomplete_filter"}
  }
}

И в моем отображении я использую это на identifierполе при индексации :

"identifier": {
  "type": "string",
  "analyzer": "autocomplete",
  "search_analyzer": "standard"
}

Это означает , что ngrams, которые индексируются для D1234являются D1, D12, D123и D1234.

Чтобы сделать запрос, я делаю следующее:

"query": {
  "bool": {
    "should": {
      "match": {
        "identifier": {
          "query": "D12",
          "fuzziness": 0
        }
      }
    }
  }
}

Это возвращает результаты от самого длинного к самому короткому, так что D12появляется в конце результатов. Как мне обеспечить, чтобы самый короткий из идентификаторов имел наивысшую оценку релевантности?

Я предполагаю, что D12запрос совпадает с ngram так: [{D12}, {D12}3, {D12}34]эластичный поиск выглядит так: «О, отлично, 3 совпадения!» а не 1 [{D12}], D12который даст результат.

Я предполагаю, что одно решение может не частично соответствовать этим ngram, так что упругий поиск видит [{D12}]оба результата, но оценивается D12выше, чем, D1234поскольку он соответствует 1/2 ngram, а не 1/4. Я не уверен, как настроить эластичный поиск, чтобы дать этот результат, хотя.

Любая помощь приветствуется.

Автор: Tobias Edwards Источник Размещён: 20.10.2019 10:28

Ответы (1)


2 плюса

Решение

Вы можете сделать это с помощью сортировки на основе сценариев , но сначала вам нужно отобразить свое identifierполе multi-fieldsследующим образом

"identifier": {
    "type": "string",
    "analyzer": "autocomplete",
    "search_analyzer": "standard",
    "fields": {
        "raw": {
            "type": "string",
            "index": "not_analyzed"
        }
    }
}

Вы должны сделать это, потому что если вы sortподключены напрямую, identifierвы получите те же результаты, потому что все они будут иметь 2-буквенные жетоны из-за edge ngram filter. После этого это даст вам желаемый результат

{
  "query": {
    "bool": {
      "should": {
        "match": {
          "identifier": {
            "query": "D12",
            "fuzziness": 0
          }
        }
      }
    }
  },
  "sort": {
    "_script": {
      "script": "doc['identifier.raw'].value.length()",
      "order": "asc",
      "type": "number"
    }
  }
}

Надеюсь это поможет!!

Автор: ChintanShah25 Размещён: 05.01.2016 03:03
Вопросы из категории :
32x32