Java 에서 Elastic Search 사용하기 - 2. Post Request (Create)

작성: 2021.06.08

수정: 2021.06.08

읽는시간: 00 분

Data/Search Engine

반응형

Java 에서 Elastic Search 사용하기2. - Post Request (Create)

https://shanepark.tistory.com/139

 

Java 에서 Elastic Search 사용하기 - Get Request

org.elasticsearch elasticsearch 7.12.1 org.elasticsearch.client elasticsearch-rest-high-level-client 7.12.1 Elastic Search client로는 High level client 와 Low level client가 있습니다. low level clie..

shanepark.tistory.com

이번에는 1편에 이어 CRUD 중 첫번째인 C 를 해보겠습니다.

 

일단 1편에서 GET 방식을 연습해보며 만들었던 모듈이 있습니다.

package best.gaia.utils;

import java.io.IOException;
import java.io.Reader;
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.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;

import com.ibatis.common.resources.Resources;


public class ElasticUtil {
	private static ElasticUtil self;
	private static RestHighLevelClient client;
	
	private ElasticUtil() throws IOException {
        Properties properties = new Properties();
        Reader reader = Resources.getResourceAsReader("best/gaia/db/dbinfo.properties");
        properties.load(reader);
        String hostname = properties.getProperty("el.url");
        int port = Integer.parseInt(properties.getProperty("el.port"));
        HttpHost host = new HttpHost(hostname, port);
        RestClientBuilder restClientBuilder = RestClient.builder(host);
        client = new RestHighLevelClient(restClientBuilder);
	};
	
	public static ElasticUtil getInstance() throws IOException {
		if(self == null)
			self = new ElasticUtil();
		return self;
	}
	
	public Map<String,Object> getReponse(String index, String id) {
		GetResponse response = null; 
		
		GetRequest getRequest = new GetRequest(index, id);
		RequestOptions options = RequestOptions.DEFAULT;
		try {
		response = client.get(getRequest, options);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return response.getSourceAsMap();
	}
}

 

이제 여기에 메서드를 추가하는건 크게 어렵지 않습니다.

	public IndexResponse create(String index, String id, String jsonBody) {
		IndexResponse response = null;
		
		IndexRequest indexRequest = new IndexRequest(index).id(id).source(jsonBody, XContentType.JSON);
		try {
			response = client.index(indexRequest, RequestOptions.DEFAULT);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return response;
	}

위와 같이 간단하게 create 메서드를 작성 해 보았습니다. 

 

	public static void main(String[] args) throws IOException {
		
		String index = "gaia";
		String id = "1";
		
		ElasticUtil elastic = ElasticUtil.getInstance();
		
//		Map<String,Object> map = elastic.getReponse(index,id);
		Map<String,Object> map  = new HashMap<>();
		map.put("새로운항목", 155);
		map.put("test", 153);
		XContentBuilder xContent = XContentFactory.jsonBuilder().map(map);
		String jsonBody = Strings.toString(xContent);
		
		IndexResponse response = elastic.create(index, id, jsonBody);
		
		System.out.println(response);
		
	}

사용할때는 위와 같이 하면 되는데요,

XContentBuilder 를 만들어서 사용해야 하는데 여간 불편한게 아닙니다. 위에서는 map이라도 썼지.. 

 

// alarm 내용을 만들어 담아 issue 작성자에게 알람을 만들어 보낸다.
			XContentBuilder alarm;
			try {
				alarm = XContentFactory.jsonBuilder()
						.startObject()
							.field("mem_no",issue.getMem_no())
							.field("alarm_type", "IC")
							.field("url",issue.getUrl())
							.field("proj_usernick",issueHistory.getHistoryWriter().getMem_nick())
							.field("issue_title",issue.getIssue_title())
							.field("issue_his_cont",issueHistory.getIssue_his_cont() )
						.endObject();
				
				// 해당 Alarm을 elastic Search에 post 해야함. 
				System.out.println(Strings.toString(alarm));
				/////// 코드 작성중 //////

제가 알람 작성용으로 작성하던 코드인데요. 필드를 하나씩 넣어서 XContentFactory를 만들려면 여간 힘든게 아닙니다.

 

	public IndexResponse create(String index, String id, Map<String, Object> data ) throws IOException {
		IndexResponse response = null;
		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);
		
		return response;
	}

그래서 index, id, 그리고 map 형태의 data를 parameter로 받아 바로 indexRequest를 하도록 코드를 작성 해 보았습니다.

 

 

package best.gaia.shanetest;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.elasticsearch.action.index.IndexResponse;
import org.springframework.stereotype.Component;

import best.gaia.utils.ElasticUtil;

@Component
public class ElasticPostRequestTest {
	
	public static void main(String[] args) throws IOException {
		
		String index = "gaia";
		String id = "1";
		
		ElasticUtil elastic = ElasticUtil.getInstance();
		
		Map<String,Object> map  = new HashMap<>();
		map.put("새로운항목", 155);
		map.put("test", 153);
		
		IndexResponse response = elastic.create(index, id, map);
		
		System.out.println(response);
		
	}
	
	
}

사용 할 때는 위 처럼  하면 됩니다. reponse 객체에는 뭐가 담겨 올지 궁금해서 만능 출력기에 넣어보았습니다.

IndexResponse[index=gaia,type=_doc,id=1,version=6,result=updated,seqNo=15,primaryTerm=3,shards={"total":2,"successful":1,"failed":0}]

index, type, id, version,result, seqNo, primaryTerm, shard 등이 나옵니다.

코드 어시스트를 받아봐도 특별히 많이 나오지는 않습니다. 방금 만든 create 함수를 바탕으로 여러가지 고레벨 모듈들을 만들어서 편하게 사용 하면 되겠습니다. 

 

저는 지금 만들고 있는 최종 팀프로젝트에서 '알람' 기능과 '메시지'기능을 위의 API를 바탕으로 준비 해 보려고 합니다.

통합검색 만들어보겠다고 조금 파보던 Elastic Search 인데 여러가지 쓰임새가 많을 듯 합니다.

혹시 잘 이해가 안되시는 분은 https://shanepark.tistory.com/139 에서 1편을 먼저 보면 어렵지 않은 코드라 쉽게 이해가 되실 겁니다.

반응형