Я подозреваю, что анализатор на ваших полях - standard
или аналогичный. Это означает, что символы типа :
и -
были удалены:
GET _analyze
{
"text": "John-Doe",
"analyzer": "standard"
}
с отображением
{
"tokens" : [
{
"token" : "john",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "doe",
"start_offset" : 5,
"end_offset" : 8,
"type" : "<ALPHANUM>",
"position" : 1
}
]
}
Давайте создадим наш собственный анализатор, который сохранит специальные символы, но строчные буквы для всех остальных символов одновременно:
PUT multisearch
{
"settings": {
"analysis": {
"analyzer": {
"with_special_chars": {
"tokenizer": "whitespace",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"properties": {
"firstName": {
"type": "text",
"fields": {
"with_special_chars": {
"type": "text",
"analyzer": "with_special_chars"
}
}
},
"ip": {
"type": "ip",
"fields": {
"with_special_chars": {
"type": "text",
"analyzer": "with_special_chars"
}
}
}
}
}
}
Прием двух образцов документов:
POST multisearch/_doc
{
"ip": "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
}
POST multisearch/_doc
{
"firstName": "John-Doe"
}
и применение вашего запроса сверху:
GET multisearch/_search
{
"query": {
"query_string": {
"fields": [
"id",
"email",
"firstName.with_special_chars",
"lastName",
"phone",
"ip.with_special_chars"
],
"query": "2001\\:0db8* OR john-*"
}
}
}
оба совпадения возвращаются.
Два замечания: 1) обратите внимание, что мы искали .with_special_chars
вместо основных полей и 2) я удалил ведущий подстановочный знак из ip - это очень неэффективно.
Последние подсказки, так как вы просили предложения по оптимизации: запрос можно переписать как
GET multisearch/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"id": "tegO63EBG_KW3EFnvQF8"
}
},
{
"match": {
"email": "john@doe.com"
}
},
{
"match_phrase_prefix": {
"firstName.with_special_chars": "john-d"
}
},
{
"match_phrase_prefix": {
"firstName.with_special_chars": "john-d"
}
},
{
"match": {
"phone.with_special_chars": "+151351"
}
},
{
"wildcard": {
"ip.with_special_chars": {
"value": "2001\\:0db8*"
}
}
}
]
}
}
}
- Частичное совпадение
id
, вероятно, излишество - либо term
ловит или нет email
может быть просто match
ed first-
& lastName
: я подозреваю, что match_phrase_prefix
более эффективен, чем wildcard
или regexp
, поэтому я бы go с этим (если вам не нужен ведущий *
) phone
может быть match
ed, но убедитесь, что специальные символы тоже могут быть сопоставлены (если вы используете формат int'l) - используйте
wildcard
для ip
- тот же синтаксис, что и в строке запроса
Попробуйте описанное выше и посмотрите, заметите ли вы улучшения скорости!