Поиск подстроки с помощью ONGR Elastic Bundle для Symfony
Я использую https://github.com/ongr-io/ElasticsearchBundle для моего проекта Symfony3. Причина этого пакета в том, что мой проект использует Propel.
До сих пор все хорошо, работает неплохо. Но теперь я хочу добавить возможность поиска подстроки слова. например, есть элементы, названные как Test01, Test02, Test03, ... и когда я пытаюсь найти, например, Test, я не получаю никаких результатов. Просто когда я набираю все слово, как Test01.
Я читал о возможности подстановочного поиска, но разные решения говорили, что использование ngram или edge_ngram было бы лучшим решением.
Я попытался указать это в конфигурации следующим образом
ongr_elasticsearch:
analysis:
filter:
incremental_filter:
type: edge_ngram
min_gram: 3
max_gram: 10
analyzer:
incrementalAnalyzer:
type: custom
tokenizer: standard
filter:
- lowercase
- incremental_filter
managers:
default:
index:
hosts:
- %elastic_host%:%elastic_port%
index_name: index
analysis:
analyzer:
- incrementalAnalyzer
filter:
- incremental_filter
mappings:
- AppBundle
Но я не получил результат, как хотел. Кто-нибудь может мне помочь с этим? Каковы различия между фильтрами и анализаторами? Я использую MultiMatchQuery, поскольку я хочу искать в разных полях разных типов:
$multiMatchQuery =
new MultiMatchQuery(
[
'name^12',
'product_name^8',
'itemno^18',
'number^7',
'category^6',
'company^4',
'motor^3',
'chassis^13',
'engine^14',
'description'
],
$term
);
$search->addQuery($multiMatchQuery);
Я также попытался определить "not_analyzed" поля.
Надеюсь на вашу помощь!
Благодарю.
2 ответа
Хорошо, я нашел решение. Вот статья, которая описывает проблему (специфично для немецкого языка) https://www.elastic.co/guide/en/elasticsearch/guide/current/ngrams-compound-words.html
Поэтому анализатору нужен фильтр Ngram (не работал с токенизатором). Я забыл также указать свойство с анализатором. теперь это сработало.
ongr_elasticsearch:
analysis:
analyzer:
my_ngram_analyzer:
type: custom
tokenizer: standard
filter:
- lowercase
- my_ngram_filter
filter:
my_ngram_filter:
type: ngram
min_gram: 2
max_gram: 8
managers:
default:
index:
hosts:
- %elastic_host%:%elastic_port%
index_name: index
analysis:
analyzer:
- my_ngram_analyzer
filter:
- my_ngram_filter
mappings:
- AppBundle
И свойство в Документе также должно быть правильно определено (для всех необходимых свойств).
/**
* @var string
*
* @ES\Property(name="itemno", type="string", options={"analyzer":"my_ngram_analyzer"})
*/
public $itemno;
Конфигурация пучка представляет собой картирование эластичного поиска. В разделе анализа вы можете определить анализаторы, где вы можете использовать их в отдельных менеджерах.
Разница между фильтрами и анализаторами заключается в том, что фильтры используются в цепочке анализаторов. Анализатор содержит цепочку действий, в которой фильтр является его частью так же, как токены, фильтры токенов и другие. Вот очень хорошая статья об анализаторе https://www.elastic.co/blog/found-text-analysis-part-1
Чтобы поиск работал так, как вам нравится, я думаю, вы должны использовать токенайзер ngram, а не фильтр. https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html