0

Так у меня есть поле 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 соответствует nграмм следующим образом: [{D12}, {D12}3, {D12}34] и эластичный поиск идет «О, отлично, 3 матча!» а не 1 [{D12}], что и результат D12.

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

Любая помощь будет высоко оценена.

+0

Какую версию ES вы используете? – ChintanShah25

+0

Я использую ES 2.1 –

+0

ли решение работает? – ChintanShah25

ответ

2

Вы можете сделать это с script based sorting, но сначала вам нужно карту вам 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" 
    } 
    } 
} 

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

+0

Привет, друг , еще раз спасибо за ваш ответ. Это сработало, когда я хотел просто запросить это одно поле, но полностью перечеркнул оценку релевантности, когда были включены другие запросы. Не уверен, что смогу спуститься по пути сортировки _script для моих требований. –

+0

Также подумал, что я упоминал о любом другом, встроенные скрипты по умолчанию отключены в более новых версиях ES (я использую ES 2.1). Вы можете включить это. или создайте скрипт как файл '.groovy' и поместите его в каталог'/config/scripts/'. –

Смежные вопросы