Как запросить ElasticSearch с подстановочным знаком - PullRequest
2 голосов
/ 14 февраля 2020

Я выполняю следующий запрос в ElasticSearch 7.5.2 и получаю ожидаемые результаты:

message:org.jooq.exception.TooManyRowsException

Но если я попытаюсь так, я не получу результатов (даже если это выглядит как более широкий запрос ):

message:*TooManyRowsException

Отображение в этом поле:

"messages": {
  "match": "*message",
  "match_mapping_type":"string",
  "mapping": {
    "type":"text",
    "analyzer":"custom_standard"
  }
}

Итак, я думаю, что я неправильно понимаю, как подстановочные знаки работают в ES. Кто-нибудь знает, почему * не соответствует «любому символу» в текстовых полях?

Спасибо.

Кстати, я тоже попробовал эти варианты без удачи:

message:*.TooManyRowsException
message:"*TooManyRowsException"
message:(*TooManyRowsException)
message:TooManyRowsException

Воспроизводимый пример

  • Создание индекса

    curl -H 'Content-Type: application/json' -XPUT localhost:9200/twitter
    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "custom_standard": {
                        "type": "custom",
                        "tokenizer": "uax_url_email",
                        "filter": ["lowercase", "snowball", "stop"]
                    }
                },
                "normalizer": {
                    "custom_lowercase": {
                        "type": "custom",
                        "filter": ["lowercase"]
                    }
                }
            }
        },
        "mappings": {
            "dynamic_templates": [
                {
                    "messages": {
                        "match": "*message",
                        "match_mapping_type":"string",
                        "mapping": {
                            "type":"text",
                            "analyzer":"custom_standard"
                        }
                    }
                }
            ]
        }
    }
  • Индекс документа

    curl -s -H 'Content-Type: application/json' -XPOST localhost:9200/twitter/_doc
    {
       "message": "org.jooq.exception.TooManyRowsException"
    }
  • Выполнить поиск, который даст результаты

    curl -s -H 'Content-Type: application/json' -XGET localhost:9200/twitter/_search
    {
        "query": {
            "query_string": {
                "query": "message:org.jooq.exception.TooManyRowsException"
            }
        }
    }
  • Выполнить поиск, который не даст результатов

    curl -s -H 'Content-Type: application/json' -XGET localhost:9200/twitter/_search
    {
        "query": {
            "query_string": {
                "query": "message:*TooManyRowsException"
            }
        }
    }

1 Ответ

1 голос
/ 14 февраля 2020

Игнорируйте это, см. Правку 2

Я думаю, вы действительно неправильно понимаете, как работают подстановочные знаки. Можете ли вы опубликовать свое полное отображение случайно? Я вижу, что вы используете dynamici c mapping , однако динамическое c mapping используется для установки типа поля в зависимости от условия и не имеет никакого отношения к поведению поиска напрямую. Так, например, ваше отображение будет принимать все строковые поля, имя которых заканчивается сообщением, и отображать их как текстовые поля.

Трудно сказать, хотите ли вы этого или нет, но если вы делаете это специально для того, чтобы разрешить поиск по шаблону, вам, вероятно, ничего этого не нужно.

Для выполнения поиск по шаблону, вам действительно нужно только * в нужном месте в строке запроса.

{
    "query": {
        "query_string": {
            "query": "*.TooManyRowsException",
            "default_field" : "message",
            "allow_leading_wildcard": true
        }
    }
}

или

{
    "query": {
        "query_string": {
            "query": "*message:.TooManyRowsException",
            "allow_leading_wildcard": true
        }
    }
}

должны соответствовать всем исключениям, которые начинаются с message: и заканчивается .TooManyRowsExceptions. Вы также можете установить default_field на messages. Более подробную информацию об этом можно найти здесь . Кроме того, запрос query_string делает намного больше, чем просто позволяет поиск по шаблону. Он анализирует ваш запрос и анализирует такие вещи, как AND или OR. Как упомянуто @Gabriel, если вам нужен только подстановочный поиск, лучше подойдет запрос подстановочный :

{
    "query": {
        "wildcard": {
            "message": {
                "value": "*.TooManyRowsException",
            }
        }
    }
}

Редактировать: Измененные примеры запросов основываясь на отзывах

Edit2: Ваш запрос действительно правильный. Проблема, похоже, в вашем кастомном анализаторе. Строка запроса совпадает с анализируемым полем, и ваш uax_email_analyzer основан на стандартном анализаторе:

{
  "analyzer": "custom_standard",
  "text": "org.jooq.exception.TooManyRowsException"
}

возвращает

{
  "tokens" : [
    {
      "token" : "org.jooq.exception.toomanyrowsexcept",
      "start_offset" : 0,
      "end_offset" : 39,
      "type" : "<ALPHANUM>",
      "position" : 0
    }
  ]
}

Следовательно, исходный запрос не будет совпадать, пока

{
    "query": {
        "query_string": {
            "query": "message:*org.jooq.exception.toomanyrowsexcept"
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...