반응형
Recent Posts
Recent Comments
관리 메뉴

개발잡부

[es] filter aggregation - high level client 본문

카테고리 없음

[es] filter aggregation - high level client

닉의네임 2023. 6. 22. 18:41
반응형

집계를 해야 하는데 쿼리 한방으로 다수의 집계 결과를 얻어야 하는데 

그게 또 조건이 다 다르네..

 

filter aggregation 을 사용해 보자 

 

Filters 에 term 조건을 복수로 넣으니 or 연산이 반영되어서 원하는 결과가 나오지 않았다. 

fliter 에 bool 쿼리도 안드어가지고

 

그래서 잴 다루기쉬운 query_string 으로 filter 생성 

 

sample 쿼리를 만들고  실행했더니 얼추 원하는 결과가 나옴 

GET hyper-item/_search
{
  "_source": [
    "docDispYn",
    "rsvDocDispYn"
  ],
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "itemNo": "146526241"
          }
        }
      ]
    }
  },
  "aggs": {
    "DISPLAY": {
      "filter": {
        "query_string": {
          "query": "Y",
          "fields": [
            "docDispYn",
            "rsvDocDispYn"
          ]
        }
      },
      "aggs": {
        "STORE_Id": {
          "terms": {
            "field": "itemStoreInfo.storeId",
            "size": 10
          }
        }
      }
    },
    "UNDISPLAY": {
      "filter": {
        "query_string": {
          "query": "docDispYn:N AND rsvDocDispYn:N"
        }
      },
      "aggs": {
        "STORE_Id": {
          "terms": {
            "field": "itemStoreInfo.storeId",
            "size": 10
          }
        }
      }
    }
  }
}

자 이제 이걸 high-level-client 로 변경 하면 

아래와 같고 

    List<AggregationBuilder> agg = new ArrayList<>();
    if (requestParam.getAggsKey() != null && requestParam.getAggsKey().size() > 0) {
        if (requestParam.getAggsKey().contains(AggsField.STORE_ID.getName())) {
            agg.add(getStoreIdTermAggs());
        }
        if (requestParam.getAggsKey().contains(AggsField.DISPLAY.getName())) {
            QueryBuilder filter = QueryBuilders.queryStringQuery("docDispYn:Y OR rsvDocDispYn:Y");
            FilterAggregationBuilder filterDisplay = AggregationBuilders.filter(AggsField.DISPLAY.getName(), filter).subAggregation(getStoreIdTermAggs());
            agg.add(filterDisplay);
        }
        if (requestParam.getAggsKey().contains(AggsField.UNDISPLAY.getName())) {
            QueryBuilder unFilter = QueryBuilders.queryStringQuery("docDispYn:N AND rsvDocDispYn:N");
            FilterAggregationBuilder filterUndisplay = AggregationBuilders.filter(AggsField.UNDISPLAY.getName(), unFilter).subAggregation(getStoreIdTermAggs());
            agg.add(filterUndisplay);
        }
    }
    sourceBuilder.aggregations(agg);
    return new CustomSearchRequest().indices(this.indices()).source(sourceBuilder).build();
}




    private AggregationBuilder getStoreIdTermAggs(){
       return  ((TermsAggregationBuilder) AggregationBuilders.terms(AggsField.STORE_ID.getName()).field(AggsField.STORE_ID.getAggsField())).size(100);
    }

이걸 Response 로 받아서 쓰려면

Map<String, Object> aggsMap = new HashMap<>();
if (searchResponse.getAggregations() != null && searchResponse.getAggregations().get(AggsField.STORE_ID.getName()) != null) {
    Terms terms = searchResponse.getAggregations().get(AggsField.STORE_ID.getName());
    aggsMap.put(AggsField.STORE_ID.getName(), this.getStoreIds(terms));
}
if (searchResponse.getAggregations() != null && searchResponse.getAggregations().get(AggsField.DISPLAY.getName()) != null) {
    Filter dispAgg = searchResponse.getAggregations().get(AggsField.DISPLAY.getName());
    Terms disp = dispAgg.getAggregations().get(AggsField.STORE_ID.getName());
    aggsMap.put(AggsField.DISPLAY.getName(), this.getStoreIds(disp));
}
if (searchResponse.getAggregations() != null && searchResponse.getAggregations().get(AggsField.UNDISPLAY.getName()) != null) {
    Filter undispAgg = searchResponse.getAggregations().get(AggsField.UNDISPLAY.getName());
    Terms undisp = undispAgg.getAggregations().get(AggsField.STORE_ID.getName());
    aggsMap.put(AggsField.UNDISPLAY.getName(), this.getStoreIds(undisp));
}





    private List<String> getStoreIds(Terms t) {
        return t.getBuckets().stream().map(x -> (String) x.getKey()).collect(Collectors.toList());
    }
반응형
Comments