엘라스틱 서치의 RestHighLevelClient를 사용하여 검색 결과 문서의 정렬하는 방법을 소개하겠습니다.
소스코드 먼저 살펴보겠습니다.
Controller
@RestController
public class TestController {
@Autowired
RestHighLevelClient client;
@Autowired
TestService testService;
@RequestMapping("/test/test.do")
List<Map<String,Object>> test(
@RequestParam(value="sort",defaultValue = "") String sort,
@RequestParam(value="department",defaultValue="") String department,
@RequestParam(value="publisher",defaultValue="") String publisher,
@RequestParam(value="age",defaultValue="") String age
) throws Exception{
return testService.sendHighLevelApi("combook_*", sort, department, publisher, age);
}
}
여려 파라미터를 받고 있습니다. sort 파라미터를 service에 메서드로 넘겨서 Return 합니다.
ServiceImpl
@Slf4j
@Service
public class TestServiceImpl implements TestService{
@Autowired
RestHighLevelClient client;
@Override
public List<Map<String, Object>> sendHighLevelApi(String indexName, String sort, String department, String publisher,
String age) throws Exception {
ArrayList<Map<String,Object>> list = null;
if("".equals(sort)) sort = "date";
log.debug("sort: "+sort);
try {
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(10000);
searchSourceBuilder.timeout(new TimeValue(60,TimeUnit.SECONDS));
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
// sort
if("date".equals(sort)) {
searchSourceBuilder.sort(new FieldSortBuilder("reg_date.keyword").order(SortOrder.ASC)); // 등록일순 정렬
} else if("cheap".equals(sort) ) {
searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC)); // 가격 싼 순
} else if("expensive".equals(sort) ) {
searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.DESC)); // 가격 비싼 순
}
searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); // score 높은순 (default)
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
list = new ArrayList<Map<String,Object>>();
for (SearchHit hit : searchHits) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
list.add(sourceAsMap);
}
}catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
필드 기준으로 정렬을 할때는 SearchSourceBuilder.sort에 FiledSortBuilder를 파라미터로 넘겨줍니다.
sort 파라미터가 빈칸, 혹은 "date" 일 때는 등록 날짜(reg_date)라는 필드로 오름차순 정렬,
"cheap" 일때는 가격(price)이라는 필드 오름차순으로 정렬합니다. 오름차순 정렬 시 가격 저렴한 순으로 정렬됩니다.
"expensive" 일때는 가격(price)이라는 필드 내림차순으로 정렬합니다. 가격이 비싼 순으로 정렬됩니다.
마지막으로 조건문 바깥에는 ScoreSortBuilder가 위치합니다. 저는 Score가 높은순으로 정렬되게 설정했습니다.
결과 확인하기
sort가 빈칸일 때 ( = date 일 때)
reg_date로 오름차순 정렬이 된 것을 확인 할 수 있습니다.
sort = cheap 일 때
price가 싼 순으로 정렬이 된 것을 확인 할 수 있습니다.
sort = expensive 일 때
price가 비싼 순으로 정렬이 되었습니다.