Jest – Elasticsearch 자바 클라이언트

1. 소개

Elasticsearch와 함께 일한 사람은 RESTful 검색 API를 사용하여 쿼리를 작성하는 것이 지루하고 오류가 발생하기 쉽다는 것을 알고 있습니다.

이 튜토리얼에서는 Elasticsearch 용 HTTP Java 클라이언트 인 Jest를 살펴 보겠습니다. Elasticsearch는 자체 네이티브 Java 클라이언트를 제공하지만 Jest는보다 유창한 API와 .

2. Maven 종속성

가장 먼저해야 할 일은 Jest 라이브러리를 POM으로 가져 오는 것입니다.

 io.searchbox jest 6.3.1 

Jest의 버전 관리는 주요 Elasticsearch 제품의 버전 관리를 따릅니다 . 이는 클라이언트와 서버 간의 호환성을 보장하는 데 도움이됩니다.

Jest 종속성을 포함하면 해당하는 Elasticsearch 라이브러리가 전이 종속성으로 포함됩니다.

3. Jest 클라이언트 사용

이 섹션에서는 Jest 클라이언트를 사용하여 Elasticsearch로 일반적인 작업을 수행하는 방법을 살펴 봅니다.

Jest 클라이언트를 사용하려면 JestClientFactory 를 사용하여 JestClient 객체를 생성하기 만하면 됩니다. 이러한 객체는 생성하는 데 비용이 많이 들고 스레드로부터 안전 하므로 애플리케이션 전체에서 공유 할 수있는 싱글 톤 인스턴스를 생성합니다.

public JestClient jestClient() { JestClientFactory factory = new JestClientFactory(); factory.setHttpClientConfig( new HttpClientConfig.Builder("//localhost:9200") .multiThreaded(true) .defaultMaxTotalConnectionPerRoute(2) .maxTotalConnection(10) .build()); return factory.getObject(); }

그러면 로컬에서 실행되는 Elasticsearch 클라이언트에 연결된 Jest 클라이언트가 생성됩니다. 이 연결 예제는 사소한 것이지만 Jest는 프록시, SSL, 인증, 심지어 노드 검색까지 완벽하게 지원합니다 .

JestClient의 클래스는 일반적인이며, 공공의 방법의 소수를 가지고있다. 우리가 사용할 주된 것은 액션 인터페이스 의 인스턴스를 취하는 execute 입니다. Jest 클라이언트는 Elasticsearch와 상호 작용하는 다양한 작업을 생성하는 데 도움이되는 여러 빌더 클래스를 제공합니다.

모든 Jest 호출의 결과는 JestResult 인스턴스입니다 . isSucceeded 를 호출하여 성공 여부를 확인할 수 있습니다 . 실패한 작업의 경우 getErrorMessage 를 호출 하여 자세한 정보를 얻을 수 있습니다.

JestResult jestResult = jestClient.execute(new Delete.Builder("1").index("employees").build()); if (jestResult.isSucceeded()) { System.out.println("Success!"); } else { System.out.println("Error: " + jestResult.getErrorMessage()); }

3.1. 지수 관리

인덱스가 있는지 확인하기 위해 IndicesExists 작업을 사용합니다 .

JestResult result = jestClient.execute(new IndicesExists.Builder("employees").build()) 

인덱스를 생성하려면 CreateIndex 작업을 사용합니다 .

jestClient.execute(new CreateIndex.Builder("employees").build());

이렇게하면 기본 설정으로 색인이 생성됩니다. 인덱스 생성 중에 특정 설정을 재정의 할 수 있습니다.

Map settings = new HashMap(); settings.put("number_of_shards", 11); settings.put("number_of_replicas", 2); jestClient.execute(new CreateIndex.Builder("employees").settings(settings).build());

또한 ModifyAliases 작업을 사용하여 별칭을 만들거나 변경하는 것도 간단 합니다.

jestClient.execute(new ModifyAliases.Builder( new AddAliasMapping.Builder("employees", "e").build()).build()); jestClient.execute(new ModifyAliases.Builder( new RemoveAliasMapping.Builder("employees", "e").build()).build());

3.2. 문서 생성

Jest 클라이언트를 사용하면 Index 액션 클래스를 사용하여 새 문서를 쉽게 인덱싱하거나 생성 할 수 있습니다 . Elasticsearch의 문서는 JSON 데이터뿐이며 인덱싱을 위해 JSON 데이터를 Jest 클라이언트에 전달하는 여러 방법이 있습니다.

이 예에서는 가상의 Employee 문서를 사용하겠습니다.

{ "name": "Michael Pratt", "title": "Java Developer", "skills": ["java", "spring", "elasticsearch"], "yearsOfService": 2 }

JSON 문서를 표현하는 첫 번째 방법은 Java String 을 사용하는 것 입니다. JSON 문자열을 수동으로 생성 할 수 있지만 적절한 형식, 중괄호 및 이스케이프 따옴표 문자에 유의해야합니다.

따라서 Jackson과 같은 JSON 라이브러리를 사용하여 JSON 구조를 빌드 한 다음 String으로 변환하는 것이 더 쉽습니다 .

ObjectMapper mapper = new ObjectMapper(); JsonNode employeeJsonNode = mapper.createObjectNode() .put("name", "Michael Pratt") .put("title", "Java Developer") .put("yearsOfService", 2) .set("skills", mapper.createArrayNode() .add("java") .add("spring") .add("elasticsearch")); jestClient.execute(new Index.Builder(employeeJsonNode.toString()).index("employees").build());

또한 Java Map 을 사용하여 JSON 데이터를 표시하고이를 Index 작업에 전달할 수 있습니다.

Map employeeHashMap = new LinkedHashMap(); employeeHashMap.put("name", "Michael Pratt"); employeeHashMap.put("title", "Java Developer"); employeeHashMap.put("yearsOfService", 2); employeeHashMap.put("skills", Arrays.asList("java", "spring", "elasticsearch")); jestClient.execute(new Index.Builder(employeeHashMap).index("employees").build());

마지막으로 Jest 클라이언트는 인덱싱 할 문서를 나타내는 모든 POJO를 수락 할 수 있습니다. Employee 클래스 가 있다고 가정 해 보겠습니다 .

public class Employee { String name; String title; List skills; int yearsOfService; }

이 클래스의 인스턴스를 인덱스 빌더에 직접 전달할 수 있습니다 .

Employee employee = new Employee(); employee.setName("Michael Pratt"); employee.setTitle("Java Developer"); employee.setYearsOfService(2); employee.setSkills(Arrays.asList("java", "spring", "elasticsearch")); jestClient.execute(new Index.Builder(employee).index("employees").build());

3.3. 문서 읽기

Jest 클라이언트를 사용하여 Elasticsearch에서 문서에 액세스하는 두 가지 기본 방법이 있습니다. 먼저 문서 ID를 알고 있으면 Get 작업을 사용하여 직접 액세스 할 수 있습니다 .

jestClient.execute(new Get.Builder("employees", "17").build());

반환 된 문서에 액세스하려면 다양한 getSource 메서드 중 하나를 호출해야합니다 . 결과를 원시 JSON으로 가져 오거나 다시 DTO로 역 직렬화 할 수 있습니다.

Employee getResult = jestClient.execute(new Get.Builder("employees", "1").build()) .getSourceAsObject(Employee.class);

문서에 액세스하는 다른 방법은 검색 작업 을 통해 Jest에서 구현되는 검색 쿼리를 사용하는 것 입니다.

Jest 클라이언트는 전체 Elasticsearch 쿼리 DSL을 지원합니다 . 인덱싱 작업과 마찬가지로 쿼리는 JSON 문서로 표현되며 검색을 수행하는 여러 방법이 있습니다.

먼저 검색 쿼리를 나타내는 JSON 문자열을 전달할 수 있습니다. 다시 말해, 문자열이 올바르게 이스케이프되고 유효한 JSON인지 확인해야합니다.

String search = "{" + " \"query\": {" + " \"bool\": {" + " \"must\": [" + " { \"match\": { \"name\": \"Michael Pratt\" }}" + " ]" + " }" + " }" + "}"; jestClient.execute(new Search.Builder(search).build());

위의 Index 작업과 마찬가지로 Jackson과 같은 라이브러리를 사용하여 JSON 쿼리 문자열을 작성할 수 있습니다.

Additionally, we can also use the native Elasticsearch query action API. The one downside of this is that our application has to depend on the full Elasticsearch library.

With the Search action, the matching documents can be accessed using the getSource methods. However, Jest also provides the Hit class, which wraps the matching documents and provides metadata about the results. Using the Hit class, we can access additional metadata for each result: score, routing, and explain results, to name a few:

List
    
      searchResults = jestClient.execute(new Search.Builder(search).build()) .getHits(Employee.class); searchResults.forEach(hit -> { System.out.println(String.format("Document %s has score %s", hit.id, hit.score)); });
    

3.4. Updating Documents

Jest provides a simple Update action for updating documents:

employee.setYearOfService(3); jestClient.execute(new Update.Builder(employee).index("employees").id("1").build());

It accepts the same JSON representations as the Index action we saw earlier, making it easy to share code between the two operations.

3.5. Deleting Documents

Deleting a document from an index is done using the Delete action. It only requires an index name and document ID:

jestClient.execute(new Delete.Builder("17") .index("employees") .build());

4. Bulk Operations

Jest client also supports bulk operations. This means we can save time and bandwidth by sending multiple operations together at the same time.

Using the Bulk action, we can combine any number of requests into a single call. We can even combine different types of requests together:

jestClient.execute(new Bulk.Builder() .defaultIndex("employees") .addAction(new Index.Builder(employeeObject1).build()) .addAction(new Index.Builder(employeeObject2).build()) .addAction(new Delete.Builder("17").build()) .build());

5. Asynchronous Operations

Jest client also supports asynchronous operations, which means we can perform any of the above operations using non-blocking I/O.

To invoke an operation asynchronously, simply use the executeAsync method of the client:

jestClient.executeAsync( new Index.Builder(employeeObject1).build(), new JestResultHandler() { @Override public void completed(JestResult result) { // handle result } @Override public void failed(Exception ex) { // handle exception } });

Note that in addition to the action (indexing in this case), the asynchronous flow also requires a JestResultHandler. The Jest client will call this object when the action has finished. The interface has two methods – completed and failed – that allow handling either success or failure of the operation, respectively.

6. Conclusion

In this tutorial, we have looked briefly at the Jest client, a RESTful Java client for Elasticsearch.

기능의 일부만 다루었지만 Jest가 강력한 Elasticsearch 클라이언트라는 것은 분명합니다. 유창한 빌더 클래스와 RESTful 인터페이스를 통해 쉽게 배울 수 있으며 Elasticsearch 인터페이스를 완벽하게 지원하므로 네이티브 클라이언트를 대체 할 수 있습니다.

항상 그렇듯이 튜토리얼의 모든 코드 예제는 GitHub에서 끝납니다.