Обработка результата поиска


(Aleksey Yasinskiy) #1

Приветствую,
Делаю обычный запрос (curl -XGET) к elastic с поиском определенного вхождения строки в поле messages. Запрос работает и возвращает помимо поля messages собственно еще и описание самого документа. Можно ли как-то в самом запросе (без пост обработки cut, awk… ) указать, что меня интересует только возврат информации с определенного поля?
Например, из всего этого (я ищу строку «The text»)

"_index": "logstash-2016.08.17",
"_type": "logs",
"_id": "AVaX_jytcYiAf5cDVSi-",
"_score": null,
"_source": {
"message": "The text ",
"@version": "1",
"@timestamp": "2016-08-17T10:13:56.479Z",
"path": "/data/syslog/systemlog.log",
"host": "host01"
},

мне только выводило "message": "The text " и "@timestamp": "2016-08-17T10:13:56.479Z"


(Igor Motov) #2

Посмотрите разделы search request - source filtering и search request - fields. Это то, что вы ищите?


(Aleksey Yasinskiy) #3

Нет, не то. В любом случае запрос у меня возвращает имя индекса, количество хитов... в JSON формате, что и следовало ожидать. Но мне бы хотелось получать на выходе только значения в искомом поле (полях), все остальное нужно откинуть. Скорей всего нужно делать внешнюю пост обработку этого JSON и выкусывать только нужные поля.


(Igor Motov) #4

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


(Aleksey Yasinskiy) #5

конечно, вот строка с запросом:

curl -XGET 'http://localhost:9200/_search' -d '{"from":0,"size":2,"query":{"query_string":{"fields":["message"],"query":""Severity=ERROR"","analyze_wildcard":false}},"filter":{"range":{"@timestamp":{"gt":"now-1006m"}}},"sort":[{"@timestamp":{"order":"desc"}}]}'

Вот запрос в удобной форме:

{
"from": 0,
"size": 2,
"query": {
"query_string": {
"fields": [
"message"
],
"query": ""Severity=ERROR"",
"analyze_wildcard": false
}
},
"filter": {
"range": {
"@timestamp": {
"gt": "now-1006m"
}
}
},
"sort": [
{
"@timestamp": {
"order": "desc"
}
}
]

Получаю следующий результат:

{
"took": 183,
"timed_out": false,
"_shards": {
"total": 521,
"successful": 520,
"failed": 1,
"failures": [
{
"shard": 0,
"index": ".kibana",
"node": "pLSXJYh3SjWaZ7NUq4XDyw",
"reason": {
"type": "search_parse_exception",
"reason": "No mapping found for [@timestamp] in order to sort on"
}
}
]
},
"hits": {
"total": 12,
"max_score": null,
"hits": [
{
"_index": "logstash-2016.08.17",
"_type": "logs",
"_id": "AVaayHJrcYiAf5cDvm06",
"_score": null,
"_source": {
"message": "Aug 17 23:14:02 host - Severity=ERROR, bla bla bla bla",
"@version": "1",
"@timestamp": "2016-08-17T23:14:02.693Z",
"path": "/data/syslog/systemlog.log",
"host": "host-nagios"
},
"sort": [
1471475642693
]
},
{
"_index": "logstash-2016.08.17",
"_type": "logs",
"_id": "AVaayHJrcYiAf5cDvm0t",
"_score": null,
"_source": {
"message": "Aug 17 23:14:02 host - Severity=ERROR, bla bla bla bla",
"@version": "1",
"@timestamp": "2016-08-17T23:14:02.692Z",
"path": "/data/syslog/systemlog.log",
"host": "host-nagios"
},
"sort": [
1471475642692
]
}
]
}
}

Из всего этого результата мне необходимо только содержимое поля "message". Я на основании его создаю письмо и отправляю нужным адресатам.
Могу ли я его отпарсить уже на уровне DSL-запроса (средствами эластика), либо это уже пост обработка (запрос curl -XGET 'query' | cut,awk ...) ?


(Igor Motov) #6

Теперь понял. Нет, такой возможности в elasticsearch пока нет. Самый компактный и удобный для пост-обработки вариант, который приходит в голову это

curl -XGET 'http://localhost:9200/_search?_source_include=message&filter_path=hits.hits._source.message&format=yaml' -d '...'

Он произведет что-то вроде:

---
hits:
  hits:
  - _source:
      message: "Aug 17 23:14:02 host - Severity=ERROR, bla bla bla bla"
  - _source:
      message: "Aug 17 23:14:02 host - Severity=ERROR, bla bla bla bla"

Остальное придется обрабатывать на вашей стороне.


(Aleksey Yasinskiy) #7

Большое спасибо!

Вот еще нашел , может кому-то будет полезным

curl -XGET "query"| python -m json.tool | egrep ""message":"

этот способ разбирает JSON построчно и затем просто грепаем нужное нам поле.


(system) #8