복붙노트

[SPRING] 필터가있는 Spring 데이터 ElasticSearch 집계

SPRING

필터가있는 Spring 데이터 ElasticSearch 집계

일부 조건에 따라 필터링 된 값에 대해 집계를 수행하려고합니다. Spring 데이터의 ElasticSearchTemplate.query () 메서드를 사용하여 쿼리를 실행하고 결과 추출기에서 결과를 가져옵니다. 히트가 올바르게 표시됩니다 (필터가 적용되고 해당 값과 일치하는 문서 만 검색됩니다). 그러나 모든 문서에서 집계가 수행됩니다. 집계는 필터링 된 값에만 적용되어야한다고 생각합니다. 다음은 내가 사용하고있는 코드입니다.

SearchQuery query = //get the query    
SearchResponse hits = template.query(query, new ResultsExtractor<SearchResponse>() {
                @Override
                public SearchResponse extract(SearchResponse response) {
                    return response;
                }
            });

문제를 더 자세히 디버깅하기 위해 스프링 데이터를 사용하는 대신 쿼리를 실행하는 코드를 작성했습니다. 다음은 코드입니다.

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();

놀랍게도이 쿼리는 올바르게 실행되고 필터는 집계에 적용되었습니다. 추가로 분석하기 위해 나는 elasticsearchtemplate의 코드를 살펴본 후 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();

위의 코드를 실행하면 스프링 데이터와 동일한 동작을 보입니다! (즉, 필터가 쿼리에는 적용되었지만 집계에는 적용되지 않았습니다. 이것은 스프링 데이터의 버그입니까? 그렇지 않다면, 원하는 방식으로 데이터를 검색하는 데 사용해야하는 다른 방법이 있습니까?

미리 감사드립니다.

해결법

  1. ==============================

    1.이 동작은 Elasticsearch에서 의도적으로 설계된 동작입니다.

    이 동작은 Elasticsearch에서 의도적으로 설계된 동작입니다.

    간단히 말하면 집계에 대한 입력과 사후 필터는 요청 본문의 쿼리 섹션과 일치하는 문서 집합입니다. 따라서 집계는 필터링 된 문서에 적용되지 않습니다.

    그러나 집계를 필터링 된 문서에 적용하려면 "쿼리 섹션 내에서 필터 이동"즉 필터링 된 쿼리를 사용하십시오. 이제 쿼리 섹션의 출력은 필터링 된 문서 집합이되며 집계는 예상대로 적용됩니다.

    따라서 요구 사항에 따라 게시 필터 대신 필터링 된 쿼리를 사용하십시오.

  2. from https://stackoverflow.com/questions/28258481/spring-data-elastisearch-aggregations-with-filters by cc-by-sa and MIT license