Задать вопрос

Elasticsearch — как искать?

Настраиваю поиск через Elasticsearch - добавил в индекс данные, задаю поиск - находит только полное совпадение слова.
Как искать подстроки?
Как искать по морфологии?
Как искать разные комбинации, например, модели товаров - "MD-501 DS" - найти по "MD501", "MD 501", "MD501DS"?

Официальная дока дает определения вроде подходящих мне фильтров, не не указывает, как их передавать в массиве параметров коннектора (в моем случае - PHP).
  • Вопрос задан
  • 2404 просмотра
Подписаться 3 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
webtop
@webtop
Web developer
Попробуйте так:

$body['query']['filtered']['query']['fuzzy_like_this'] = array(
	'fields' => ['field_name'],
	'like_text' => 'some text',
	'max_query_terms' => 1000000,
	'fuzziness' => 3,
	'prefix_length' => 3
);
Ответ написан
Комментировать
@freecod Автор вопроса
Спасибо, работает, но к сожалению регистрозависимо и не покрывает все задачи.
Полагаю, нужно добавить фильтры и анализаторы, есть пример из доки:

$params = array(
            'index' => 'reuters',
            'body' => array(
                'settings' => array(
                    'number_of_shards' => 1,
                    'number_of_replicas' => 0,
                    'analysis' => array(
                        'filter' => array(
                            'shingle' => array(
                                'type' => 'shingle'
                            )
                        ),
                        'char_filter' => array(
                            'pre_negs' => array(
                                'type' => 'pattern_replace',
                                'pattern' => '(\\w+)\\s+((?i:never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint))\\b',
                                'replacement' => '~$1 $2'
                            ),
                            'post_negs' => array(
                                'type' => 'pattern_replace',
                                'pattern' => '\\b((?i:never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint))\\s+(\\w+)',
                                'replacement' => '$1 ~$2'
                            )
                        ),
                        'analyzer' => array(
                            'reuters' => array(
                                'type' => 'custom',
                                'tokenizer' => 'standard',
                                'filter' => array('lowercase', 'stop', 'kstem', 'word_delimiter', 'snowball')
                            )
                        )
                    )
                ),
                'mappings' => array(
                    '_default_' => array(
                        'properties' => array(
                            'title' => array(
                                'type' => 'string',
                                'analyzer' => 'reuters',
                                'term_vector' => 'yes',
                                'copy_to' => 'combined'
                            ),
                            'body' => array(
                                'type' => 'string',
                                'analyzer' => 'reuters',
                                'term_vector' => 'yes',
                                'copy_to' => 'combined'
                            ),
                            'combined' => array(
                                'type' => 'string',
                                'analyzer' => 'reuters',
                                'term_vector' => 'yes'
                            ),
                            'topics' => array(
                                'type' => 'string',
                                'analyzer' => 'reuters',
                            ),
                            'places' => array(
                                'type' => 'string',
                                'index' => 'not_analyzed'
                            )
                        )
                    ),
                    'my_type' => array(
                        'properties' => array(
                            'my_field' => array(
                                'type' => 'string'
                            )
                        )
                    )
                )
            )
        );


но не ясно, как потом в поиске использовать созданый фильтр - все примеры в json с запросом к HTTP серверу эластика.
Ответ написан
Комментировать
@Mirocow
Регитро независимый

По умолчанию в Eldsticseach включен регистрозависимый анализатор поиска. Для его отключения используем ниже следующие настройки в конфигурационом файле elasticsearch.yml

settings:
                index:
                    analysis:
                        analyzer:
                            string_lowercase:
                                tokenizer: keyword
                                filter: lowercase


Устанавливаем lowercase в elasticsearch и преобразовываем строку запроса в lowercase
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы