엘라스틱서치 집계 작업

데이터 생성:

​<br></br>    @Test<br></br>    public void 색인생성(){<br></br>        /**<br></br>         * 색인 생성<br></br>         * */<br></br>        클라이언트.admin().indices().prepareCreate("선수").get();<br></br>    }<br></br>​<br></br>​<br></br>​<br></br>    /**<br></br>     * 매핑 생성<br></br>     */<br></br>    @Test<br></br>    public void 매핑생성_부스트() throws Exception{<br></br>        /**<br></br>         * 형식:<br></br>         "mappings": {<br></br>            "선수": {<br></br>                "properties": {<br></br>                     "이름": {"index": "not_analyzed","type": "string"},<br></br>                    "나이": {"type": "integer"},<br></br>                    "연봉": {"type": "integer"},<br></br>                    "팀": {"index": "not_analyzed","type": "string"},<br></br>                    "포지션": {"index": "not_analyzed","type": "string"}<br></br>                }<br></br>            }<br></br>         }<br></br>​<br></br>         */<br></br>        //JSON 형식으로 데이터 구성, 매핑 생성<br></br>        XContentBuilder 매핑빌더 = XContentFactory.jsonBuilder()<br></br>                .startObject()<br></br>                .startObject("선수")<br></br>                .startObject("properties")<br></br>                .startObject("이름").field("type","string").field("index", "not_analyzed").endObject()<br></br>                .startObject("나이").field("type","integer").endObject()<br></br>                .startObject("연봉").field("type","integer").endObject()<br></br>                .startObject("팀").field("type","string").field("index", "not_analyzed").endObject()<br></br>                .startObject("포지션").field("type","string").field("index", "not_analyzed").endObject()<br></br>                .endObject()<br></br>                .endObject()<br></br>                .endObject();<br></br>        PutMappingRequest 요청 = Requests.putMappingRequest("선수")<br></br>                .type("선수")<br></br>                .source(매핑빌더);<br></br>        클라이언트.admin().indices().putMapping(요청).get();<br></br>    }<br></br>​<br></br>    @Test<br></br>    public void 대량문서삽입() throws IOException {<br></br>        BulkRequestBuilder 대량요청빌더 = 클라이언트.prepareBulk();<br></br>​<br></br>// 클라이언트#prepare 또는 Requests#를 사용하여 직접 인덱스/삭제 요청 생성<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "1")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "곡덕강")<br></br>                        .field("나이", 33)<br></br>                        .field("연봉",3000)<br></br>                        .field("팀" , "cav")<br></br>                        .field("포지션" , "sf")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "2")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "어천")<br></br>                        .field("나이", 25)<br></br>                        .field("연봉",2000)<br></br>                        .field("팀" , "cav")<br></br>                        .field("포지션" , "pg")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "3")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "월운붕")<br></br>                        .field("나이", 29)<br></br>                        .field("연봉",1000)<br></br>                        .field("팀" , "war")<br></br>                        .field("포지션" , "pg")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "4")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "손월")<br></br>                        .field("나이", 26)<br></br>                        .field("연봉",2000)<br></br>                        .field("팀" , "war")<br></br>                        .field("포지션" , "sg")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "5")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "장운뢰")<br></br>                        .field("나이", 26)<br></br>                        .field("연봉",2000)<br></br>                        .field("팀" , "war")<br></br>                        .field("포지션" , "pf")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "6")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "에디슨")<br></br>                        .field("나이", 40)<br></br>                        .field("연봉",1000)<br></br>                        .field("팀" , "tim")<br></br>                        .field("포지션" , "pf")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "7")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "뉴턴")<br></br>                        .field("나이", 21)<br></br>                        .field("연봉",500)<br></br>                        .field("팀" , "tim")<br></br>                        .field("포지션" , "c")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "8")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "아인슈타인")<br></br>                        .field("나이", 21)<br></br>                        .field("연봉",300)<br></br>                        .field("팀" , "tim")<br></br>                        .field("포지션" , "sg")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>        대량요청빌더.add(클라이언트.prepareIndex("선수", "선수", "9")<br></br>                .setSource(jsonBuilder()<br></br>                        .startObject()<br></br>                        .field("이름", "테슬라")<br></br>                        .field("나이", 20)<br></br>                        .field("연봉",500)<br></br>                        .field("팀" , "tim")<br></br>                        .field("포지션" , "sf")<br></br>                        .endObject()<br></br>                )<br></br>        );<br></br>​<br></br>​<br></br>        BulkResponse 응답 = 대량요청빌더.get();<br></br>        if (응답.hasFailures()) {<br></br>            // 각 대량 요청 항목을 반복하여 실패 처리<br></br>        }<br></br>    }<br></br>​<br></br>​

1: 그룹화 및 카운트

각 팀의 선수 수 계산:

select 팀, count(*) as 선수_수 from 선수 group by 팀;

@Test<br></br>public void 그룹화_카운트() {<br></br>    //1: 쿼리 구성<br></br>    SearchRequestBuilder 빌더 = 클라이언트.prepareSearch("선수").setTypes("선수");<br></br>    //2: 집계 조건 지정<br></br>    TermsAggregationBuilder 팀 = AggregationBuilders.terms("선수_수").field("팀");<br></br>    //3: 집계 조건을 쿼리에 추가<br></br>    빌더.addAggregation(팀);<br></br>    //4: 실행 및 응답 반환<br></br>    SearchResponse 검색응답 = 빌더.get();<br></br>    //5: 응답을 맵으로 변환<br></br>    Map<String, Aggregation> 집계맵 = 검색응답.getAggregations().asMap();<br></br>    //6: 집계 필드 추출<br></br>    StringTerms 팀집계 = (StringTerms)집계맵.get("선수_수");<br></br>    System.out.println(팀집계);<br></br>    //7: 집계 필드 반복<br></br>    Iterator<StringTerms.Bucket> 반복자 = 팀집계.getBuckets().iterator();<br></br>    while (반복자.hasNext()){<br></br>        StringTerms.Bucket 버킷 = 반복자.next();<br></br>        System.out.println("각 팀 :" + 버킷.getKey() + "에는 【"+버킷.getDocCount()+"】 명의 선수가 있습니다");<br></br>    }<br></br>​<br></br>}<br></br>​<br></br>​

2: 다중 필드 그룹화

각 팀의 각 포지션별 선수 수 계산 select 팀, 포지션, count(*) as 포지션_수 from 선수 group by 팀,포지션;

/**<br></br> * 다중 필드 그룹화<br></br> * 각 팀의 각 포지션별 선수 수 계산<br></br> * select 팀, 포지션, count(*) as 포지션_수 from 선수 group by 팀, 포지션;<br></br> * */<br></br>@Test<br></br>public void 다중필드_그룹화() {<br></br>    //1: 쿼리 구성<br></br>    SearchRequestBuilder 빌더 = 클라이언트.prepareSearch("선수").setTypes("선수");<br></br>    //2: 집계 조건 지정<br></br>    TermsAggregationBuilder 팀 = AggregationBuilders.terms("팀_집계").field("팀");<br></br>    TermsAggregationBuilder 포지션 = AggregationBuilders.terms("포지션_집계").field("포지션");<br></br>    //상위-하위 관계 주의<br></br>팀.subAggregation(포지션);<br></br>    //3: 집계 조건을 쿼리에 추가<br></br>    빌더.addAggregation(팀).addAggregation(포지션);<br></br>    //4: 실행 및 응답 반환<br></br>    SearchResponse 검색응답 = 빌더.get();<br></br>    //5: 응답을 맵으로 변환<br></br>    Map<String, Aggregation> 집계맵 = 검색응답.getAggregations().asMap();<br></br>    //6: 집계 필드 추출<br></br>    StringTerms 팀집계 = (StringTerms)집계맵.get("팀_집계");<br></br>    //7: 집계 필드 반복<br></br>    Iterator<StringTerms.Bucket> 반복자 = 팀집계.getBuckets().iterator();<br></br>    while (반복자.hasNext()){<br></br>        StringTerms.Bucket 버킷 = 반복자.next();<br></br>        //8: 모든 하위 집계 가져오기<br></br>        Map<String, Aggregation> 포지션맵 = 버킷.getAggregations().asMap();<br></br>        StringTerms 포지션집계 = (StringTerms)포지션맵.get("포지션_집계");<br></br>        //9: 하위 집계 내용 반복 - 팀--포지션--선수<br></br>        Iterator<StringTerms.Bucket> 하위반복자 = 포지션집계.getBuckets().iterator();<br></br>        while (하위반복자.hasNext()){<br></br>            StringTerms.Bucket 하위버킷 = 하위반복자.next();<br></br>            System.out.println("팀 :" + 버킷.getKey() + "의 "+하위버킷.getKey()+" 포지션에는"+하위버킷.getDocCount() + "명의 선수가 있습니다");<br></br>        }<br></br>    }<br></br>}<br></br>​<br></br>​

3: 그룹화 및 최대값 계산

각 팀의 선수 최대/최소/총합/평균 나이 계산

select 팀, max(나이) as 최대_나이 from 선수 group by 팀;

​<br></br>/**<br></br> * 그룹화: 최대값, 최소값, 평균값 계산<br></br> * 각 팀의 선수 최대/최소/총합/평균 나이 계산<br></br> select 팀, max(나이) as 최대_나이 from 선수 group by 팀;<br></br> *<br></br> * */<br></br>@Test<br></br>public void 그룹화_최대값(){<br></br>    //1: 쿼리 구성<br></br>    SearchRequestBuilder 빌더 = 클라이언트.prepareSearch("선수").setTypes("선수");<br></br>    //2: 집계 조건 지정<br></br>    TermsAggregationBuilder 팀 = AggregationBuilders.terms("팀_집계").field("팀");<br></br>    //3: 최대값을 조회할 필드 지정<br></br>    MaxAggregationBuilder 나이필드 = AggregationBuilders.max("최대_나이").field("나이");<br></br>    //상위-하위 관계 설정<br></br>    팀.subAggregation(나이필드);<br></br>    //3: 집계 조건을 쿼리에 추가<br></br>    빌더.addAggregation(팀);<br></br>    //4: 실행 및 응답 반환<br></br>    SearchResponse 검색응답 = 빌더.get();<br></br>    //5: 응답을 맵으로 변환<br></br>    Map<String, Aggregation> 집계맵 = 검색응답.getAggregations().asMap();<br></br>    //6: 집계 필드 추출<br></br>    StringTerms 팀집계 = (StringTerms)집계맵.get("팀_집계");<br></br>    //7: 집계 필드 반복<br></br>    Iterator<StringTerms.Bucket> 반복자 = 팀집계.getBuckets().iterator();<br></br>    while (반복자.hasNext()){<br></br>        StringTerms.Bucket 버킷 = 반복자.next();<br></br>        //8: 모든 하위 집계 가져오기<br></br>        Map 나이맵 = 버킷.getAggregations().asMap();<br></br>        int 나이 = (int)((InternalMax) 나이맵.get("최대_나이")).getValue();<br></br>        System.out.println("팀 :" + 버킷.getKey() + "  최대 난이: "+나이);<br></br>    }<br></br>}<br></br>​<br></br>​

4: 그룹화 및 최소값 계산

각 팀의 선수 최대/최소/총합/평균 나이 계산 select 팀, min(나이) as 최소_나이 from 선수 group by 팀;

/**<br></br> * 그룹화: 최대값, 최소값, 평균값 계산<br></br> * 각 팀의 선수 최대/최소/총합/평균 나이 계산<br></br> select 팀, min(나이) as 최소_나이 from 선수 group by 팀;<br></br> *<br></br> * */<br></br>@Test<br></br>public void 그룹화_최소값(){<br></br>    //1: 쿼리 구성<br></br>    SearchRequestBuilder 빌더 = 클라이언트.prepareSearch("선수").setTypes("선수");<br></br>    //2: 집계 조건 지정<br></br>    TermsAggregationBuilder 팀 = AggregationBuilders.terms("팀_집계").field("팀");<br></br>    //3: 최소값을 조회할 필드 지정<br></br>    MinAggregationBuilder 나이필드 = AggregationBuilders.min("최소_나이").field("나이");<br></br>    //상위-하위 관계 설정<br></br>    팀.subAggregation(나이필드);<br></br>    //3: 집계 조건을 쿼리에 추가<br></br>    빌더.addAggregation(팀);<br></br>    //4: 실행 및 응답 반환<br></br>    SearchResponse 검색응답 = 빌더.get();<br></br>    //5: 응답을 맵으로 변환<br></br>    Map<String, Aggregation> 집계맵 = 검색응답.getAggregations().asMap();<br></br>    //6: 집계 필드 추출<br></br>    StringTerms 팀집계 = (StringTerms)집계맵.get("팀_집계");<br></br>    //7: 집계 필드 반복<br></br>    Iterator<StringTerms.Bucket> 반복자 = 팀집계.getBuckets().iterator();<br></br>    while (반복자.hasNext()){<br></br>        StringTerms.Bucket 버킷 = 반복자.next();<br></br>        //8: 모든 하위 집계 가져오기<br></br>        Map 나이맵 = 버킷.getAggregations().asMap();<br></br>        int 나이 = (int)((InternalMin) 나이맵.get("최소_나이")).getValue();<br></br>        System.out.println("팀 :" + 버킷.getKey() + "  최소 나이: "+나이);<br></br>    }<br></br>}<br></br>​<br></br>​

5: 그룹화 및 평균값 계산

각 팀의 선수 최대/최소/총합/평균 나이 계산 select 팀, avg(나이) as 평균_나이 from 선수 group by 팀;

/**<br></br> * 그룹화: 최대값, 최소값, 평균값 계산<br></br> * 각 팀의 선수 최대/최소/총합/평균 나이 계산<br></br> select 팀, avg(나이) as 평균_나이 from 선수 group by 팀;<br></br> *<br></br> * */<br></br>@Test<br></br>public void 그룹화_평균값(){<br></br>    //1: 쿼리 구성<br></br>    SearchRequestBuilder 빌더 = 클라이언트.prepareSearch("선수").setTypes("선수");<br></br>    //2: 집계 조건 지정<br></br>    TermsAggregationBuilder 팀 = AggregationBuilders.terms("팀_집계").field("팀");<br></br>    //3: 평균값을 조회할 필드 지정<br></br>    AvgAggregationBuilder 나이필드 = AggregationBuilders.avg("평균_나이").field("나이");<br></br>    //상위-하위 관계 설정<br></br>    팀.subAggregation(나이필드);<br></br>    //3: 집계 조건을 쿼리에 추가<br></br>    빌더.addAggregation(팀);<br></br>    //4: 실행 및 응답 반환<br></br>    SearchResponse 검색응답 = 빌더.get();<br></br>    //5: 응답을 맵으로 변환<br></br>    Map<String, Aggregation> 집계맵 = 검색응답.getAggregations().asMap();<br></br>    //6: 집계 필드 추출<br></br>    StringTerms 팀집계 = (StringTerms)집계맵.get("팀_집계");<br></br>    //7: 집계 필드 반복<br></br>    Iterator<StringTerms.Bucket> 반복자 = 팀집계.getBuckets().iterator();<br></br>    while (반복자.hasNext()){<br></br>        StringTerms.Bucket 버킷 = 반복자.next();<br></br>        //8: 모든 하위 집계 가져오기<br></br>        Map 나이맵 = 버킷.getAggregations().asMap();<br></br>        Double 나이 = ((InternalAvg) 나이맵.get("평균_나이")).getValue();<br></br>        System.out.println("팀 :" + 버킷.getKey() + "  평균 나이: "+나이);<br></br>    }<br></br>}<br></br>​<br></br>​

6: 그룹화 및 합계 계산

각 팀 선수의 평균 나이와 총 연봉 계산 select 팀, avg(나이)as 평균_나이, sum(연봉) as 총연봉 from 선수 group by 팀;

/**<br></br> * 그룹화: 최대값, 최소값, 평균값 계산<br></br> * 각 팀 선수의 평균 나이와 총 연봉 계산<br></br> select 팀, avg(나이)as 평균_나이, sum(연봉) as 총연봉 from 선수 group by 팀;<br></br> *<br></br> * */<br></br>@Test<br></br>public void 그룹화_합계(){<br></br>    //1: 쿼리 구성<br></br>    SearchRequestBuilder 빌더 = 클라이언트.prepareSearch("선수").setTypes("선수");<br></br>    //2: 집계 조건 지정<br></br>    TermsAggregationBuilder 팀 = AggregationBuilders.terms("팀_집계").field("팀");<br></br>    //3: 조회할 필드 지정<br></br>    AvgAggregationBuilder 나이필드 = AggregationBuilders.avg("평균_나이").field("나이");<br></br>​<br></br>    SumAggregationBuilder 연봉필드= AggregationBuilders.sum("총연봉").field("연봉");<br></br>    //상위-하위 관계 설정<br></br>    팀.subAggregation(나이필드).subAggregation(연봉필드);<br></br>    //3: 집계 조건을 쿼리에 추가<br></br>    빌더.addAggregation(팀);<br></br>    //4: 실행 및 응답 반환<br></br>    SearchResponse 검색응답 = 빌더.get();<br></br>    //5: 응답을 맵으로 변환<br></br>    Map<String, Aggregation> 집계맵 = 검색응답.getAggregations().asMap();<br></br>    //6: 집계 필드 추출<br></br>    StringTerms 팀집계 = (StringTerms)집계맵.get("팀_집계");<br></br>    //7: 집계 필드 반복<br></br>    Iterator<StringTerms.Bucket> 반복자 = 팀집계.getBuckets().iterator();<br></br>    while (반복자.hasNext()){<br></br>        StringTerms.Bucket 버킷 = 반복자.next();<br></br>        //8: 모든 하위 집계 가져오기<br></br>        Map 나이맵 = 버킷.getAggregations().asMap();<br></br>​<br></br>        Double 나이 = ((InternalAvg) 나이맵.get("평균_나이")).getValue();<br></br>        double 총연봉 = ((InternalSum) 나이맵.get("총연봉")).getValue();<br></br>        System.out.println("팀 :" + 버킷.getKey() + "  평균 나이: "+나이 + "  팀 총연봉: " + 총연봉);<br></br>    }<br></br>}<br></br>​<br></br>​

7: 집계 정렬

각 팀의 총 연봉을 계산하고, 총 연봉을 기준으로 내림차순 정렬 select 팀, sum(연봉) as 총연봉 from 선수 group by 팀 order by 총연봉 desc;

/**<br></br> * 정렬<br></br> 각 팀의 총 연봉을 계산하고, 총 연봉을 기준으로 내림차순 정렬<br></br> select 팀, sum(연봉) as 총연봉 from 선수 group by 팀 order by 총연봉 desc;<br></br> * */<br></br>@Test<br></br>public void 그룹화_정렬(){<br></br>    /**<br></br>     *<br></br>     * TermsBuilder 팀집계= AggregationBuilders.terms("팀").order(Order.aggregation("총연봉 ", false);<br></br>     SumBuilder 연봉집계= AggregationBuilders.avg("총연봉 ").field("연봉");<br></br>     sbuilder.addAggregation(팀집계.subAggregation(연봉집계));<br></br>     * */<br></br>​<br></br>    //1: 쿼리 구성<br></br>    SearchRequestBuilder 빌더 = 클라이언트.prepareSearch("선수").setTypes("선수");<br></br>    //2: 집계 조건 지정<br></br>    TermsAggregationBuilder 팀 = AggregationBuilders.terms("팀_집계").field("팀")<br></br>            .order(Terms.Order.aggregation("총연봉", false));//false는 내림차순, true는 오름차순<br></br>    //3: 조회할 필드 지정<br></br>    SumAggregationBuilder 연봉필드= AggregationBuilders.sum("총연봉").field("연봉");<br></br>    //상위-하위 관계 설정<br></br>    팀.subAggregation(연봉필드);<br></br>    //3: 집계 조건을 쿼리에 추가<br></br>    빌더.addAggregation(팀);<br></br>    //4: 실행 및 응답 반환<br></br>    SearchResponse 검색응답 = 빌더.get();<br></br>    //5: 응답을 맵으로 변환<br></br>    Map<String, Aggregation> 집계맵 = 검색응답.getAggregations().asMap();<br></br>    //6: 집계 필드 추출<br></br>    StringTerms 팀집계 = (StringTerms)집계맵.get("팀_집계");<br></br>    //7: 집계 필드 반복<br></br>    Iterator<StringTerms.Bucket> 반복자 = 팀집계.getBuckets().iterator();<br></br>    while (반복자.hasNext()){<br></br>        StringTerms.Bucket 버킷 = 반복자.next();<br></br>        //8: 모든 하위 집계 가져오기<br></br>        Map 연봉맵 = 버킷.getAggregations().asMap();<br></br>​<br></br>        double 총연봉 = ((InternalSum) 연봉맵.get("총연봉")).getValue();<br></br>        System.out.println("팀 :" + 버킷.getKey() + "  팀 총연봉: " + 총연봉);<br></br>    }<br></br>}<br></br>​<br></br>​

태그: 엘라스틱서치 집계 자바 API

5월 24일 03:06에 게시됨