Elastic Stack/Elastic Search

Spring Boot - ElasticSearch RestHighLevelClient 범위 검색하기 (rangeQuery)

super728 2021. 11. 24. 17:03

RestHighLevelClient의 rangeQuery를 사용하여 범위 검색하는 예제를 다뤄보겠습니다. 

 

Controller

@RestController
public class TestController {
	
	@Autowired
	TestService testService;
	
	@RequestMapping("/test/test.do")
	Map<String, Object> test() throws Exception{
		return testService.doSearch();
	}
}

RestController 어노테이션을 통해 리턴되는 값을 JSON형태로 화면에 출력하도록 하였습니다. 

1. ~~ 이상 ~~ 이하 쿼리

Service

@Service
public class TestServiceImpl implements TestService{
	
	@Autowired
	RestHighLevelClient client;

	@Override
	public Map<String,Object> doSearch() throws Exception {
		Map<String,Object> resultMap = new HashMap<String,Object>();
		try {
			SearchRequest searchRequest = new SearchRequest("combook*"); // 인덱스명
			SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
			searchSourceBuilder.size(10000);
			searchSourceBuilder.timeout(new TimeValue(60,TimeUnit.SECONDS));
			
			
			searchSourceBuilder.query(QueryBuilders.rangeQuery("book_id").gte(40).lte(50)); // book_id가 40이상 50이하
			searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));  // score 높은순 (default)
			searchSourceBuilder.sort(new FieldSortBuilder("book_id").order(SortOrder.ASC)); // id오름차순 정렬
			
			searchRequest.source(searchSourceBuilder);
			SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 검색 요청
			SearchHits hits = searchResponse.getHits();
			TotalHits totalHits = hits.getTotalHits(); // total 검색 건수
			
			SearchHit[] searchHits = hits.getHits();
			List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
			list = new ArrayList<Map<String,Object>>();
			for (SearchHit hit : searchHits) {
				Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // 검색 결과를 Map으로 한건 한건 받아서 list에 추가
				list.add(sourceAsMap);
			}
			resultMap.put("totalHits", totalHits.value);
			resultMap.put("searchResults", list);
		}catch (Exception e) {
			e.printStackTrace();
			resultMap.put("totalHits", -500);
			resultMap.put("exception", e);
		}
		return resultMap;
	}
}

searchSourceBuilder.query(QueryBuilders.rangeQuery("book_id").gte(40).lte(50)) 부분에 gte는 이상, lte는 이하입니다. 

book_id가 40 이상, 50 이하인 결과 값을 가져오는 쿼리입니다. 

결과 확인

예상한 대로 book_id가 40~50까지 총 11건의 결과가 도출되었습니다. 

2. ~~ 초과 ~~ 미만 쿼리

Service

searchSourceBuilder.query(QueryBuilders.rangeQuery("book_id").gt(40).lt(50)); // book_id가 40초과 50미만

rangeQuery의 gte를 gt, lte를 lt로 변경하여 이상 이하에서 초과 미만으로 요청을 바꾸어봅니다. 

결과 확인

book_id가 41~49까지의 결과 총 9건이 도출되었습니다.