Regexp не работает в ES DSL-запрос
Отображение моего поиска Elastic выглядит следующим образом:
{
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1"
}
},
"mappings": {
"node": {
"properties": {
"field1": {
"type": "keyword"
},
"field2": {
"type": "keyword"
},
"query": {
"properties": {
"regexp": {
"properties": {
"field1": {
"type": "keyword"
},
"field2": {
"type": "keyword"
}
}
}
}
}
}
}
}
}
Проблема в следующем:
Я формирую ES-запросы с использованием asticsearch_dsl Q(). Он прекрасно работает в большинстве случаев, когда мой запрос содержит какие-либо сложные регулярные выражения. Но он полностью потерпит неудачу, если он содержит символ регулярного выражения '!' в этом. Это не дает никакого результата, когда поисковый термин содержит "!" в этом.
Например:
1.) Q('regexp', field1 = "^[a-z]{3}.b.*")
(работает отлично)
2.) Q('regexp', field1 = "^f04.*")
(работает отлично)
3.)Q('regexp', field1 = "f00.*")
(работает отлично)
4.) Q('regexp', field1 = "f04baz?")
(работает отлично)
Сбой в нижнем случае:
5.) Q('regexp', field1 = "f04((?!z).)*")
(Не дает результатов вообще)
Я попытался добавить "анализатор": "ключевое слово" вместе с "тип": "ключевое слово", как указано выше, в полях, но в этом случае ничего не работает.
В браузере я попытался проверить, как анализатор: ключевое слово будет работать на входе в случае, если это не удается:
http://localhost:9210/search/_analyze?analyzer=keyword&text=f04((?!z).)*
Кажется, выглядит хорошо здесь с результатом:
{
"tokens": [
{
"token": "f04((?!z).)*",
"start_offset": 0,
"end_offset": 12,
"type": "word",
"position": 0
}
]
}
Я выполняю свои запросы, как показано ниже:
search_obj = Search(using = _conn, index = _index, doc_type = _type).query(Q('regexp', field1 = "f04baz?"))
count = search_obj.count()
response = search_obj[0:count].execute()
logger.debug("total nodes(hits):" + " " + str(response.hits.total))
Пожалуйста, помогите, это действительно досадная проблема, так как все символы регулярного выражения прекрасно работают во всех запросах, кроме!
Кроме того, как я могу проверить, какой анализатор в настоящее время применяется с вышеуказанными настройками в моих сопоставлениях?
1 ответ
Механизм регулярных выражений Lucene ElasticSearch не поддерживает любые типы обходных путей. Документация по регулярным выражениям ES довольно двусмысленна, говоря о том, что .*
очень медленный, а также использование регулярных выражений с поиском (что не только неоднозначно, но и неправильно), так как обходные пути, если их использовать с умом, могут значительно ускорить сопоставление регулярных выражений).
Поскольку вы хотите сопоставить любую строку, которая содержит f04
и не содержит z
вы можете использовать
[^z]*fo4[^z]*
подробности
[^z]*
- любые 0+ символов кромеz
fo4
-fo4
подстрока[^z]*
- любые 0+ символов кромеz
,
Если у вас есть строка из нескольких символов, которую нужно "исключить" (скажем, z4
скорее, чем z
), вы можете использовать свой подход, используя оператор дополнения:
.*f04.*&~(.*z4.*)
Это означает почти то же самое, но не поддерживает разрывы строк:
.*
- любые символы кроме новой строки, как можно большеf04
-f04
.*
- любые символы кроме новой строки, как можно больше&
- А ТАКЖЕ~(.*z4.*)
- любая строка, кроме той, которая имеетz4