#elasticsearch #elasticsearch-query
#elasticsearch #elasticsearch-запрос
Вопрос:
Я хочу выполнить запрос, эквивалентный следующему запросу MYSQL
SELECT http_user, http_req_method, dst dst_port count(*) as total
FROM my_table
WHERE http_req_method='GET' OR http_req_method="POST"
GROUP BY http_user, http_req_method, dst dst_port
Я создал следующий запрос:
{
"query":{
"bool":{
"should":[
{
"term":{"http_req_method":"GET"}
},
{
"term":{"http_req_method":"POST"}
}
],
}
},
"aggs":{
suser":{
"terms":{
"field":"http_user"
},
"aggs":{
"dst":{
"terms":{
"field":"dst"
},
"aggs":{
"dst_port":{
"terms":{
"field":"dst_port"
},
"aggs":{
"http_req_method":{
"terms":{
"field":"http_req_method"
}
}
}
}
}
}
}
}
}
}
(Возможно, я пропускаю некоторые ветки там, но в моем коде это правильно). Проблема в том, что результаты также включают другие методы, такие как CONNECT, хотя я запрашиваю только GET или POST. Я думал, что агрегирование применяется к результатам после запроса. Я делаю что-то не так здесь?
Комментарии:
1. Можете ли вы рассказать, как вы отправляете свой запрос?
2. вы пытались добавить
"minimum_should_match": 1
?3. Добавление «minimum_should_match»: 1 сделало свое дело. Спасибо!
Ответ №1:
Я бы использовал "minimum_should_match"
, например, так:
"query":{
"bool":{
"minimum_should_match": 1,
"should":[
{
"term":{"http_req_method":"GET"}
},
{
"term":{"http_req_method":"POST"}
}
],
}
},
Другим способом, который работает лучше, было бы использовать terms
запрос в bool/filter
предложении вместо этого
"query":{
"bool":{
"filter":[
{
"terms": {"http_req_method": ["GET", "POST"] }
}
]
}
},
Комментарии:
1. ДА… Это сработало. Не могли бы вы подробнее объяснить, почему?
2. Я добавил еще один способ не заботиться о
should
иminimum_should_match
.
Ответ №2:
Согласно последней документации Elasticsearch, вы должны переместить часть фильтра внутри агрегации. Что-то вроде этого:
{
"aggs":{
get_post_requests":{
"filter" : {
"bool": [
{ "term":{"http_req_method":"GET"} },
{ "term":{"http_req_method":"POST"} },
]
},
"aggs": {
"suser"{
"terms":{
"field":"http_user"
}
},
"aggs":{
"dst":{
"terms":{
"field":"dst"
},
"aggs":{
"dst_port":{
"terms":{
"field":"dst_port"
},
"aggs":{
"http_req_method":{
"terms":{
"field":"http_req_method"
}
}
}
}
}
}
}
}
}
}
}
Надеюсь, что скобки в порядке. Дайте мне знать, если это приблизит вас к результату 🙂
Комментарии:
1. В документации Elasticsearch говорится следующее: агрегацию можно рассматривать как единицу работы, которая создает аналитическую информацию по набору документов. Контекст выполнения определяет, что представляет собой этот набор документов (например, агрегация верхнего уровня выполняется в контексте выполняемого запроса / фильтров поискового запроса). Под этим я понимаю, что agg должны применяться к отфильтрованному запросу