https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/_search_apis.html
이번에는 엘라스틱 서치를 사용하는 이유인 검색을 해 보도록 하겠습니다. 일단 작성한 코드 먼저 보여드리겠습니다.
client로 search 명령을 주면 , response를 return 합니다.
해당 response는 SearchHits 라는 Iterable 구현체를 가지고 있습니다.
지네릭 타입은 SearchHit 입니다.
해당 SerarchHit에서 각각 source를 getSourceAsMap() 메서드를 통해 받고, 모두 list에 추가 해 줍니다.
그러면 검색 결과를 간단하게 Map에 담아 반환 받을 수 있습니다.
RestHighLevelClient의 search 메서드는 parameter로 SearchRequest와 RequestOption을 받습니다.
searchRequest는 다음과 같이 만들었습니다.
이렇게 해서 index와 query, sort 를 파라미터로 받아 간단한 검색을 한 뒤 List<Map<String,Object>> 형태로 반환하는 메서드를 만들었습니다.
코드를 한번 실행 해 보겠습니다.
package shane;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.search.sort.SortOrder;
import best.gaia.utils.ElasticUtil;
public class ElasticSearchTest {
public static void main(String[] args) throws IOException {
ElasticUtil elastic = ElasticUtil.getInstance();
String index = "alarm";
Map<String,Object> query = new HashMap<>();
query.put("mem_no",4);
Map<String,SortOrder> sort = new HashMap<>();
sort.put("date",SortOrder.DESC);
List<Map<String, Object>> list = elastic.simpleSearch(index, query, sort);
for(Map<String, Object> map : list) {
System.out.println(map);
}
}
}
alarm 이라는 index 에서 mem_no 는 4 에 해당하는 document 들을 불러와 date 의 내림차순대로 정렬하라는 명령을 내려 보겠습니다.
나름 생각보다 어렵지 않게 원하는 결과를 조회 받을 수 있었습니다.
오늘 짜둔 간단한 코드 아래 올려드릴 테니 참고해서 사용해주세요
package best.gaia.utils;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.http.HttpHost;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import com.ibatis.common.resources.Resources;
public class ElasticUtil {
private static ElasticUtil self;
private RestClientBuilder restClientBuilder;
private ElasticUtil() {
Properties properties = new Properties();
try { // dbinfo.properties에서 접속 정보 받아옵니다.
properties.load(Resources.getResourceAsReader("best/gaia/db/dbinfo.properties"));
} catch (IOException e) {}
String hostname = properties.getProperty("el.url");
int port = Integer.parseInt(properties.getProperty("el.port"));
HttpHost host = new HttpHost(hostname, port);
restClientBuilder = RestClient.builder(host);
};
public static ElasticUtil getInstance() {
if(self == null)
self = new ElasticUtil();
return self;
}
public List<Map<String,Object>> simpleSearch(
String index
, Map<String,Object> query
, Map<String,SortOrder> sort
){
// search에 index 조건 걸기
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// query에 있는 셋 쿼리 조건으로 걸기
for(String key : query.keySet()) {
searchSourceBuilder.query(QueryBuilders.matchQuery(key, query.get(key)));
}
// sort 에 있는 셋을 정렬 조건으로 걸기
for(String key : sort.keySet()) {
searchSourceBuilder.sort(new FieldSortBuilder(key).order(sort.get(key)));
}
searchRequest.source(searchSourceBuilder);
List<Map<String,Object>> list = new ArrayList<>();
try(RestHighLevelClient client = new RestHighLevelClient(restClientBuilder)) {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
for(SearchHit hit : searchHits) {
Map<String, Object> sourceMap = hit.getSourceAsMap();
list.add(sourceMap);
}
} catch (IOException e) {}
return list;
}
public Map<String,Object> getReponse(String index, String id){
GetResponse response = null;
GetRequest getRequest = new GetRequest(index, id);
RequestOptions options = RequestOptions.DEFAULT;
try (RestHighLevelClient client = new RestHighLevelClient(restClientBuilder)) {
response = client.get(getRequest, options);
} catch (IOException e) {}
return response.getSourceAsMap();
}
public int insert(String index, String id, Map<String, Object> data ){
IndexResponse response = null;
try(RestHighLevelClient client = new RestHighLevelClient(restClientBuilder)) {
data.put("date", LocalDateTime.now());
XContentBuilder xContent = XContentFactory.jsonBuilder().map(data);
String jsonBody = Strings.toString(xContent);
IndexRequest indexRequest = new IndexRequest(index).id(id).source(jsonBody, XContentType.JSON);
response = client.index(indexRequest, RequestOptions.DEFAULT);
} catch (IOException e) {}
return response.getShardInfo().getSuccessful();
}
}
나름 위에서 작성한 유틸을 바탕으로 service 와 dao를 만들어서 잘 활용 해 보고 있습니다.
잘 이해가 되지 않는 다면 가장 쉬운 1번글 부터 차근차근 보면 어렵지 않게 이해하실 수 있을 겁니다.
https://shanepark.tistory.com/139
+ 추가로 모듈화 후 현재 Spring bean에 등록해서 사용 중인 Component 입니다.
package best.gaia.utils;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.http.HttpHost;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;
import com.ibatis.common.resources.Resources;
@Component
public class ElasticUtil {
private RestClientBuilder restClientBuilder;
private ElasticUtil() {
Properties properties = new Properties();
try { // dbinfo.properties에서 접속 정보 받아옵니다.
properties.load(Resources.getResourceAsReader("best/gaia/db/dbinfo.properties"));
} catch (IOException e) {}
String hostname = properties.getProperty("el.url");
int port = Integer.parseInt(properties.getProperty("el.port"));
HttpHost host = new HttpHost(hostname, port);
restClientBuilder = RestClient.builder(host);
};
/**
* @param index
* @param query Map<String, Object> key는 프로퍼티명, object는 value 조건
* @param sort Map<String, SortOrder>
* @param size (null 넣을 수 있습니다. size null일 경우 모두 받아옴)
* @return
*/
public List<Map<String,Object>> simpleSearch(
String index
, Map<String,Object> query
, Map<String,SortOrder> sort
, Integer size
){
/*
* search API 참고 주소
* https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-search.html
*/
// search에 index 조건 걸기
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// query에 있는 셋 쿼리 조건으로 걸기
for(String key : query.keySet()) {
searchSourceBuilder.query(QueryBuilders.matchQuery(key, query.get(key)));
}
// sort 에 있는 셋을 정렬 조건으로 걸기
for(String key : sort.keySet()) {
searchSourceBuilder.sort(new FieldSortBuilder(key).order(sort.get(key)));
}
if(size != null) {
searchSourceBuilder.size(size);
}
searchRequest.source(searchSourceBuilder);
List<Map<String,Object>> list = new ArrayList<>();
try(RestHighLevelClient client = new RestHighLevelClient(restClientBuilder)) {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
for(SearchHit hit : searchHits) {
Map<String, Object> sourceMap = hit.getSourceAsMap();
list.add(sourceMap);
}
} catch (IOException e) {}
return list;
}
public Map<String,Object> getReponse(String index, String id){
GetResponse response = null;
GetRequest getRequest = new GetRequest(index, id);
RequestOptions options = RequestOptions.DEFAULT;
try (RestHighLevelClient client = new RestHighLevelClient(restClientBuilder)) {
response = client.get(getRequest, options);
} catch (IOException e) {}
return response.getSourceAsMap();
}
public int insert(String index, Map<String, Object> data ){
IndexResponse response = null;
try(RestHighLevelClient client = new RestHighLevelClient(restClientBuilder)) {
data.put("date", LocalDateTime.now());
XContentBuilder xContent = XContentFactory.jsonBuilder().map(data);
String jsonBody = Strings.toString(xContent);
// id 없이 삽입시 자동 UID가 생성됩니다.
String id = null;
IndexRequest indexRequest = new IndexRequest(index).id(id).source(jsonBody, XContentType.JSON);
response = client.index(indexRequest, RequestOptions.DEFAULT);
} catch (IOException e) {}
return response.getShardInfo().getSuccessful();
}
}
'Data > Search Engine' 카테고리의 다른 글
docker로 elastic search 띄우기 (0) | 2021.11.25 |
---|---|
docker-compose 이용해 ELK Stack 구축하기 (0) | 2021.09.20 |
Java 에서 Elastic Search 사용하기 - 2. Post Request (Create) (0) | 2021.06.08 |
Java 에서 Elastic Search 사용하기 - 1. Get Request (0) | 2021.06.07 |
Logstash를 이용해 Oracle 데이터를 Elastic search와 동기화 하기 (0) | 2021.06.06 |