Весенние данные ElastiSearch с фильтрами
Я пытаюсь выполнить агрегирование значений, отфильтрованных по некоторым условиям. Я использую ElasticSearchTemplate.query() метод данных Spring тоже выполнить запрос и получить результаты в экстракторе результатов. Я получаю хиты правильно (т.е. применяются фильтры и документы, соответствующие этим значениям, только извлекаются). Тем не менее, агрегация выполняется на всех документах. Я считаю, что агрегации должны применяться только к отфильтрованным значениям. Ниже приведен код, который я использую:
SearchQuery query = //get the query
SearchResponse hits = template.query(query, new ResultsExtractor<SearchResponse>() {
@Override
public SearchResponse extract(SearchResponse response) {
return response;
}
});
Чтобы продолжить отладку проблемы, я написал код для выполнения запроса, а не с использованием данных Spring. Ниже приведен код:
SearchRequestBuilder builder = esSetup.client().prepareSearch("document");
builder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), query.getFilter()));
builder.addFields(query.getFields().toArray(new String[query.getFields().size()]));
for(AbstractAggregationBuilder aggregation : query.getAggregations()){
builder.addAggregation(aggregation);
}
SearchResponse response = builder.get();
К моему удивлению, этот запрос был выполнен правильно, и фильтры были применены и к агрегатам. Чтобы проанализировать дальше, я просмотрел код упругого поиска и обнаружил, что он использует setPostFilter
метод для установки фильтра. Затем я изменил свой код, чтобы установить фильтр таким образом:
SearchRequestBuilder builder = esSetup.client().prepareSearch("document");
// builder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), query.getFilter()));
builder.setPostFilter(query.getFilter());
builder.addFields(query.getFields().toArray(new String[query.getFields().size()]));
for(AbstractAggregationBuilder aggregation : query.getAggregations()){
builder.addAggregation(aggregation);
}
SearchResponse response = builder.get();
Когда я выполнил приведенный выше код, он показал то же поведение, что и данные Spring! (т.е. фильтры были применены к запросу, но не к агрегатам. Является ли это ошибкой весенних данных? Если нет, то есть ли какой-то другой метод, который мне следует использовать для получения данных так, как я хочу?
Заранее спасибо.
1 ответ
Такое поведение разработано в Elasticsearch.
Проще говоря, вход в агрегаты И пост-фильтр - это набор документов, которые соответствуют query
раздел тела запроса. Следовательно, агрегации не применяются к отфильтрованным документам.
Однако, если вы хотите, чтобы агрегаты применялись к отфильтрованным документам, "переместите фильтры внутрь query
раздел ", то есть использовать фильтрованный запрос. Теперь вывод query
В разделе будет отфильтрованный набор документов, и агрегации будут применяться к ним, как и ожидалось.
Поэтому для ваших требований используйте фильтрованный запрос вместо пост-фильтра.