2014-01-14 2 views
3

У меня возникают проблемы с правильным выражением регулярного выражения для фильтра регулярных выражений ElasticSearch. Я пытаюсь сопоставить что-либо в «info-for/media» в поле url, например. http://mydomain.co.uk/info-for/media/press-release-1. Чтобы попробовать правильное выражение, я использую сейчас match_all, но в итоге это будет match_phrase с строкой запроса пользователя.ElasticSearch Regexp Filter

POST для локального хоста: 9200/_search

{ 
"query" : { 
       "match_all" : { }, 
       "filtered" : { 
          "filter" : { 
            "regexp": { 
             "url":".*info-for/media.*" 
            } 
          } 
       } 
     }, 
} 

Это возвращает 0 хиты, но разобрать правильно. .*info.* действительно получает результаты, содержащие URL-адрес, но, к сожалению, слишком широк, например. сопоставляя любые URL-адреса, содержащие «информацию». Как только я добавлю дефис в «info-for», я снова получаю 0 результатов. Независимо от того, какую комбинацию escape-символов я пытаюсь, я либо получаю исключение синтаксического анализа, либо нет совпадений. Может ли кто-нибудь помочь объяснить, что я делаю неправильно?

ответ

7

Во-первых, старайтесь никогда не использовать регулярные выражения или подстановочные знаки, которые не имеют префикса. То, как выполняется поиск .*foo.*, заключается в том, что каждый член словаря индекса сопоставляется с шаблоном, который, в свою очередь, строится в OR-запрос совпадающих терминов. Это O (n) в количестве уникальных терминов в вашем корпусе с последующим поиском, который довольно дорог.

Эта статья имеет некоторые подробности о том, что: https://www.found.no/foundation/elasticsearch-from-the-bottom-up/

Во-вторых, ваш URL, вероятно, метках таким образом, что делает «Info-за» и «СМИ» отдельных терминов в индексе. Таким образом, в словаре нет info-for/media -term для соответствия регулярному выражению.

Что вы, вероятно, захотите сделать, это проиндексировать путь и домен отдельно, с помощью path_hierarchy -tokenizer, чтобы сгенерировать условия.

Ниже приведен пример, который показывает, как генерируются маркеры: https://www.found.no/play/gist/ecf511d4102a806f350b#analysis

Т.е. /foo/bar/baz генерирует токены /foo/bar/baz, /foo/bar, /foo и домен foo.example.com является лексемой к foo.example.com, example.com, com

поиска что-нибудь в поле ниже /foo/bar затем может быть простым термин фильтр соответствия path:/foo/bar. Это более мощный фильтр, который также можно кэшировать.

+1

Простейший вариант состоит в том, чтобы сопоставить это поле как многополюсное поле с неанализируемой версией и запустить фильтр регулярных выражений в поле, которое не было проанализировано. В общем, регулярный фильтр имеет больше смысла в неаналитическом поле. –

+0

Это будет очень дорогостоящий запрос. –

+0

Спасибо @AlexBrasetvik У меня возникли трудности с отправкой версии JSON конфигурации отображения/анализатора в конечную точку index_settings. Он не может найти анализатор, который я объявил. Образец JSON был бы действительно полезен, если бы у вас его было, спасибо. – idlemind