‘Should’ bool запрос извлекает нежелательные результаты

#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 должны применяться к отфильтрованному запросу