эластичный поисковый запрос с willcard и escape-символами - PullRequest
0 голосов
/ 03 февраля 2019

мы используемasticsearch на freebsd 11. У нас много данных в формате ipv4, ipv6 в таблице.

Клиенты хотят искать с помощью wilcard.например

*192* -> no problem
*192.168.* -> no problem
*2001:db8* -> take error
*2001\:db8 -> take error....

Я не взял правильные данные из эластика.Особенно это касается ":".

Моя системная информация и результаты запроса:

Эластичная информация:

{
  "name": "WxaxEg6",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "o-7IPcD3RjODelTyPYUBJw",
  "version": {
    "number": "5.6.8",
    "build_hash": "688ecce",
    "build_date": "2018-02-16T16:46:30.010Z",
    "build_snapshot": false,
    "lucene_version": "6.6.1"
  },
  "tagline": "You Know, for Search"
}

Моя тестовая таблица

{
  "ip_test2": {
    "aliases": {},
    "mappings": {
      "doc": {
        "properties": {
          "ip_addr": {
            "type": "text"
          }
        }
      }
    },
    "settings": {
      "index": {
        "creation_date": "1549119687946",
        "number_of_shards": "5",
        "number_of_replicas": "1",
        "uuid": "Aljv_81nQDKx3B3Fs2nVOA",
        "version": {
          "created": "5060899"
        },
        "provided_name": "ip_test2"
      }
    }
  }
}

запрос 1:

{
    "query": {
        "query_string" : {
            "fields" : ["ip_addr"],
            "query": "*192.*",
            "analyze_wildcard": true
       }
    }
}'

Результат

{"took":3,"timed_out":false,"_shards": 
{"total":5,"successful":5,"skipped":0,"failed":0},"hits": 
{"total":255,"max_score":1.0,"hits": 
 ...:{"ip_addr": "192.168.1.4"}},

без проблем.

запрос 2

 "query": "*2001*",

Результат

{"took":5,"timed_out":false,"_shards": 
{"total":5,"successful":5,"skipped":0,"failed":0},"hits": 
{"total":100,"max_score":1.0,"hits": 
...:{"ip_addr": "2001:db8:100:0:2359:8a17:17c6:e316"}},

Нет проблем.Теперь проблема запуска.Запрос

"query": "*2001:*",

Результат

"error":{"root_cause": 
[{"type":"query_shard_exception","reason":"Failed to parse query 
[*2001:*]","index_uuid":"Aljv_81nQDKx3B3Fs2nVOA","index":"ip_test2"}]

Запрос

"query": "\"*2001:db*\"",

Результат неверный , много данных начинаются с 2001:db8

"took":1,"timed_out":false,"_shards": 
{"total":5,"successful":5,"skipped":0,"failed":0},"hits": 
{"total":0,"max_score":null,"hits":[]}}

Запрос

"query": "\"*2001:db8*\"",

Результат правильный , удивительно .... WHYYYY

{"took":2,"timed_out":false,"_shards": 
{"total":5,"successful":5,"skipped":0,"failed":0},"hits": 
{"total":100,"max_score":1.8449252,

тип поля не ipЯ не понимаю разные результаты.

может кто-нибудь объяснить мне

Мое последнее решение -

{"from":0,"size":100,"sort":[{"start_time": 
{"order":"desc","unmapped_type":"boolean"}}],
"query":{"bool":{"must":[{"range":{"start_time": 
{"gte":1546678703407,"lte":1549270703407,"format":"epoch_millis"}}},
            {"bool":{"should":[{"multi_match": 
{"query":"2001:db","fields":["ip_dst_saddr"],"type":"phrase_prefix"}},
                       {"query_string":{"query":"*2001\\:db*","fields": 
["ip_dst_saddr"],"analyze_wildcard":true}}]}}]}}}

1 Ответ

0 голосов
/ 04 февраля 2019

Для запроса

"query": "*2001:*" вам нужно экранировать двоеточие (см. здесь для более подробного примера), поэтому попробуйте использовать "query": "*2001\\:*"

Затем длядругой запрос, вы не можете использовать подстановочный знак внутри соответствия фразы (см. здесь для более подробной информации)

Если вы используете API проверки в вашем запросе:

POST <your_index>/_validate/query?explain=true
{
    "query": {
        "query_string" : {
            "fields" : ["ip_addr"],
            "query": "\"*2001:db*\"",
            "analyze_wildcard": true
       }
    }
}

вы увидите, что этот запрос объяснен

"explanations": [
    {
      "index": "<your_index>",
      "valid": true,
      "explanation": """ip_addr:"2001 db""""
    }
  ]

и "query": "\"*2001:db8*\""

"explanations": [
    {
      "index": "test_so",
      "valid": true,
      "explanation": """ip_addr:"2001 db8""""
    }
  ]

Таким образом, запрос "query": "\"*2001:db*\"" будет соответствовать только документу с токеном "2001"и "db" в том же порядке (полный токен "db", а не "db8" или что-либо еще), а запрос "query": "\"*2001:db8*\"" будет соответствовать любому документу, содержащему "2001" и "db8" в том же порядке.

Вы действительно должны использовать тип данных IP эластичного поиска.

...