Как сделать частичное совпадение в Elasticsearch?
У меня есть ссылка типа http://drive.google.com и я хочу, чтобы матч "Гугл" из ссылки.
Я:
query: {
bool : {
must: {
match: { text: 'google'}
}
}
}
но это только соответствует, если весь текст "google" (без учета регистра, поэтому он также соответствует Google или GooGlE и т. д.). Как я могу соответствовать "google" внутри другой строки?
5 ответов
дело в том, что регулярное выражение ElasticSearch, которое вы используете требует полная строка match:
узоры Люсена всегда закреплены. Шаблон при условии должен соответствовать всей строке.
таким образом, чтобы соответствовать любому символу (но новой строке), вы можете использовать .*
шаблон:
match: { text: '.*google.*'}
^^ ^^
еще один вариант для случаев, когда ваша строка может иметь строки: match: { text: '(.|\n)*google(.|\n)*'}
. Этот ужасно!--3--> является обязательным в ElasticSearch, потому что этот вкус regex не позволяет никаких [\s\S]
обходные пути, ни любые DOTALL/Singleline флаги. "механизм регулярных выражений Lucene не совместим с Perl, но поддерживает меньший диапазон операторов."
для более общего решения вы можете использовать другой анализатор или определить свой собственный. Я предполагаю, что вы используете стандартный анализатор, который разделит http://drive.google.com в маркеры "http" и "drive.google.com". Вот почему поиск только google не работает, потому что он пытается сравнить его с полным "drive.google.com".
Если вместо этого вы индексировали свои документы с помощью простого анализатора, он разделил бы его на " http", "Диск", "google"и " com". Это позволит вам соответствовать любому из этих условий самостоятельно.
Я не могу найти breaking change отключение регулярных выражений в match
, а match: { text: '.*google.*'}
не работает ни на одном из моих кластеров Elasticsearch 6.2. Возможно, он настраивается?
Regexp работает:
"query": {
"regexp": { "text": ".*google.*"}
}
для частичного сопоставления вы можете использовать префикс или match_phrase_prefix.