Jest — ElasticSearch Java 客戶端
1. 介紹
任何使用過Elasticsearch的人都知道,使用基於rest的搜尋API構建查詢可能是單調乏味且容易出錯的。
在本教程中,我們將研究Jest,一個用於Elasticsearch的HTTP Java客戶端。Elasticsearch提供了自己原生的Java客戶端,然而 Jest提供了更流暢的API和更容易使用的介面。
2. Maven 依賴
我們需要做的第一件事是匯入Jest庫到我們的POM檔案中:
<dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>6.3.1</version> </dependency>
Jest的版本是遵循Elasticsearch的主版本號的。
這將確保客戶端和服務端之間的相容性。
通過包含Jest依賴項,相應的[Elasticsearch庫](https://search.maven.org/search?q=g:org.elasticsearch a:elasticsearch)將被包含為傳遞依賴項。
3. 使用Jest Client
在本節中,我們將研究如何使用Jest client執行Elasticsearch中的常見任務。
要使用Jest client,我們只需使用 JestClientFactory
public JestClient jestClient() { JestClientFactory factory = new JestClientFactory(); factory.setHttpClientConfig( new HttpClientConfig.Builder("http://localhost:9200") .multiThreaded(true) .defaultMaxTotalConnectionPerRoute(2) .maxTotalConnection(10) .build()); return factory.getObject(); }
這裡將建立一個Jest client,該客戶端連線到本地執行的Elasticsearch。雖然這個連線示例很簡單,但是Jest還完全支援代理、SSL、身份驗證,甚至節點發現。
JestClient 類是通用類,只有少數公共方法。我們將使用的一個主要方法是execute,它接受Action介面的一個例項。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. 管理索引
檢查索引是否存在,我們使用IndicatesExists
操作:
JestResult result = jestClient.execute(new IndicesExists.Builder("employees").build())
建立一個索引,我們使用CreateIndex
操作:
jestClient.execute(new CreateIndex.Builder("employees").build());
這將建立一個具有預設設定的索引。我們可以在建立索引時覆蓋特定的設定:
Map<String, Object> 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 client使用索引操作類索引或建立新文件變得容易。Elasticsearch中的文件只是JSON資料,有多種方法可以將JSON資料傳遞給Jest client 進行索引。
對於這個例子,讓我們使用一個虛構的僱員文件:
{
"name": "Michael Pratt",
"title": "Java Developer",
"skills": ["java", "spring", "elasticsearch"],
"yearsOfService": 2
}
表示JSON文件的第一種方法是使用Java字串。雖然我們可以手動建立JSON字串,但我們必須注意正確的格式、大括號和轉義引號字元。因此,更容易的方式是使用一個JSON庫(如Jackson)來構建我們的JSON結構,然後將其轉換為字串:
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資料,並將其傳遞給索引操作:
Map<String, Object> 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 client 可以接受表示要索引的文件的任何POJO。假設我們有一個Employee類:
public class Employee {
String name;
String title;
List<String> skills;
int yearsOfService;
}
我們可以把這個類的一個例項直接傳遞給Index builder:
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 client從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 client 支援全部的 Elasticsearch query DSL。 與索引操作一樣,查詢被表示為JSON文件,並且有多種執行搜尋的方法。
首先,我們可以傳遞一個表示搜尋查詢的JSON字串。提醒一下,我們必須確保字串是正確轉義的,並且是有效的JSON:
String search = "{" +
" \"query\": {" +
" \"bool\": {" +
" \"must\": [" +
" { \"match\": { \"name\": \"Michael Pratt\" }}" +
" ]" +
" }" +
" }" +
"}";
jestClient.execute(new Search.Builder(search).build());
與上面的索引操作一樣,我們可以使用Jackson之類的庫來構建JSON查詢字串。此外,我們還可以使用原生的Elasticsearch查詢操作API。這樣做的一個缺點是,我們的應用程式必須依賴於完整的Elasticsearch庫。
我們可以使用 getSource 方法來訪問搜尋操作中匹配的文件。然而,Jest還提供了Hit類,它包裝了匹配的文件並提供有關結果的元資料。 使用Hit類,我們可以訪問每個結果的附加元資料:得分、路由和解釋結果,舉幾個例子:
List<SearchResult.Hit<Employee, Void>> 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. 更新文件
Jest為更新文件提供了一個簡單的Update操作:
employee.setYearOfService(3);
jestClient.execute(new Update.Builder(employee).index("employees").id("1").build());
它接受與我們前面看到的索引操作相同的JSON表示,這使得在兩個操作之間共享程式碼變得很容易。
3.5. 刪除文件
從索引中刪除文件是使用Delete操作完成的。它只需要索引名和文件ID:
jestClient.execute(new Delete.Builder("17")
.index("employees")
.build());
4. 批量操作
Jest client 同樣支援批量操作。 這意味著我們可以通過同時傳送多個操作來節省時間和頻寬。
使用批量操作,我們可以將任意數量的請求組合成單個呼叫。我們甚至可以將不同型別的請求組合在一起:
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. 非同步操作
Jest client 同樣支援非同步操作。 這意味著我們可以使用非阻塞I/O執行上述任何操作。
要非同步呼叫操作,只需使用客戶端的executeAsync
方法:
jestClient.executeAsync(
new Index.Builder(employeeObject1).build(),
new JestResultHandler<JestResult>() {
@Override public void completed(JestResult result) {
// handle result
}
@Override public void failed(Exception ex) {
// handle exception
}
});
注意,除了(本例中是索引)操作之外,非同步流還需要一個JestResultHandler
。當操作完成時,Jest client 將呼叫該物件。該介面有兩個方法—完成和失敗—分別允許處理操作的成功或失敗。
6. 結論
在本教程中,我們簡要介紹了Jest client,一個用於Elasticsearch的RESTful Java客戶端。雖然我們只介紹了它的一小部分功能,但很明顯Jest是一個健壯的Elasticsearch客戶端。它的流暢的構建器類和RESTful介面使其易於學習,並且它對Elasticsearch介面的完全支援使其成為原生客戶端的一個有力的替代方案。
和往常一樣,本教程中的所有程式碼示例都在我們的Github頁面上。
原文:https://www.baeldung.com/elasticsearch-jest
作者:Michael Pratt
譯者:huowolf/