在 上一篇文章 中,我們介紹了 Easysearch Java SDK 2.0.x 的基本使用和批量操作。本文將深入探討索引管理相關的功能,包括索引的創建、刪除、開關、刷新、滾動等操作,以及新版 SDK 提供的同步和異步兩種調用方式。
SDK 的對象構建有兩種方式
1. 傳統的 Builder 方式
最基礎的方式,像這樣:
CreateIndexResponse createResponse = client.indices().create(
new CreateIndexRequest.Builder()
.index("my-index")
.aliases("foo",
new Alias.Builder().isWriteIndex(true).build()
)
.build()
);
優點簡單直觀,但稍顯笨重。
2. Lambda 表達式方式
這才是推薦的寫法,簡潔優雅:
CreateIndexResponse createResponse = client.indices()
.create(c -> c
.index("my-index")
.aliases("foo", a -> a
.isWriteIndex(true)
)
);
Lambda 方式不僅代碼少,最大的優點是不用記那麼多 Builder 類名。尤其是寫複雜查詢的時候,代碼層次感特別強:
// 命名建議:用 b0、b1 這樣的簡寫表示嵌套層級
SearchResponse<Doc> results = client.search(b0 -> b0
.index("my-index")
.query(b1 -> b1
.bool(b2 -> b2
.must(b3 -> b3
.match(b4 -> b4
.field("title")
.query("搜索")
)
)
.filter(b3 -> b3
.range(b4 -> b4
.field("date")
.gte("2024-01-01")
)
)
)
),
Doc.class
);
好了,説回索引管理
啥是索引管理?
簡單來説就是對索引進行增刪改查的一些基本操作。比如:
- 建個新索引
- 刪掉不要的索引
- 關閉/打開某個索引
- 刷新一下讓數據立馬能搜到
- 清個緩存
- 整理一下索引段(讓搜索更快)
新版 SDK 在這塊的設計特別貼心,同步異步都支持,用起來特別順手。
同步方式怎麼用?
上代碼!下面這段代碼基本涵蓋了日常用到的所有索引管理操作:
String index = "test1";
// 先看看索引在不在
if (client.indices().exists(r -> r.index(index)).value()) {
LOGGER.info("Deleting index " + index);
// 在的話就刪掉重來
DeleteIndexResponse deleteIndexResponse =
client.indices().delete(new DeleteIndexRequest.Builder().index(index).build());
LOGGER.info(deleteIndexResponse.toString());
}
// 建個新的
LOGGER.info("Creating index " + index);
CreateIndexResponse createIndexResponse =
client.indices().create(req -> req.index(index));
// 關閉索引
CloseIndexResponse closeIndexResponse =
client.indices().close(req -> req.index(index));
// 打開索引
OpenResponse openResponse =
client.indices().open(req -> req.index(index));
// 刷新一下,讓剛寫入的數據馬上能搜到
RefreshResponse refreshResponse =
client.indices().refresh(req -> req.index(index));
// 把內存裏的數據都寫到磁盤上
FlushResponse flushResponse =
client.indices().flush(req -> req.index(index));
// 整理一下索引段,搜索會快很多
// maxNumSegments(1L) 意思是整理成一個段
ForcemergeResponse forcemergeResponse =
client.indices().forcemerge(req -> req.index(index).maxNumSegments(1L));
看代碼就能明白,這些操作都特別直觀,基本上方法名就能告訴你它是幹啥的。而且返回的 Response 對象裏都帶着詳細的執行結果,出了問題很容易排查。
異步方式又是咋回事?
有時候你可能不想等着這些操作一個個完成,這時候就可以用異步方式:
String index = "test1";
EasysearchAsyncClient asyncClient = SampleClient.createAsyncClient();
// 用CompletableFuture串起來一串操作
asyncClient.indices().exists(req -> req.index(index))
.thenCompose(exists -> {
if (exists.value()) {
LOGGER.info("Deleting index " + index);
return asyncClient.indices().delete(r -> r.index(index))
.thenAccept(deleteResponse -> {
LOGGER.info(deleteResponse);
});
}
return CompletableFuture.completedFuture(null);
})
.thenCompose(v -> {
LOGGER.info("Creating index " + index);
return asyncClient.indices().create(req -> req.index(index));
})
.whenComplete((createResponse, throwable) -> {
if (throwable != null) {
LOGGER.error("哎呀出錯了", throwable);
} else {
LOGGER.info("搞定!");
}
})
.get(30, TimeUnit.SECONDS); // 最多等30秒
異步方式看起來代碼多了點,但是好處也很明顯:
- 不會卡住主線程
- 可以併發執行多個操作
- 配合 CompletableFuture 能實現很多花樣
小貼士
-
選哪種方式?
- 簡單場景用同步,代碼簡單直觀
- 要併發或者不想阻塞就用異步
-
記得處理異常
- 同步的就直接 try-catch
- 異步的用 whenComplete 或 exceptionally 來處理
-
性能方面
- force merge 挺耗資源的,建議半夜執行
- refresh 太頻繁會影響寫入性能,根據需要權衡
自動翻轉 (Rollover)
在管理 Easysearch 索引時,我們經常需要控制單個索引的大小和時間跨度。Easysearch 的 Rollover API 提供了一個優雅的解決方案,允許我們基於特定條件自動創建新索引。本文將介紹如何使用 Java API 實現索引 rollover。
什麼是 Rollover?
Rollover 是一種索引管理機制,當現有索引滿足一個或多個條件時(如達到一定大小、文檔數量或時間),會自動創建一個新索引。這對於日誌管理等場景特別有用。
實現示例
首先,我們需要創建一個初始索引並設置別名:
String index = "test-00001";
// 如果索引存在則刪除
if (client.indices().exists(r -> r.index(index)).value()) {
client.indices().delete(new DeleteIndexRequest.Builder().index(index).build());
}
// 創建索引並設置別名
client.indices().create(req -> req
.index(index)
.aliases("test_log", a -> a.isWriteIndex(true)));
配置 Rollover 條件
有兩種方式配置 rollover 條件:
方式一:使用 Java API
RolloverResponse res = client.indices().rollover(req -> req
.alias("test_log")
.conditions(c -> c
.maxDocs(100L) // 文檔數量超過100
.maxAge(b -> b.time("7d")) // 索引年齡超過7天
.maxSize("5gb"))); // 索引大小超過5GB
方式二:使用 JSON 配置
String conditionsJson = """
{
"conditions": {
"max_docs": 100,
"max_age": "7d",
"max_size": "5gb"
}
}
""";
RolloverResponse response = client.indices().rollover(req -> req
.alias("test_log")
.withJson(new StringReader(conditionsJson))
);
Rollover 條件説明
- max_docs: 索引中的最大文檔數
- max_age: 索引最大存在時間
- max_size: 索引的最大存儲大小
當滿足任一條件時,系統會自動創建新索引。新索引的命名規則是將原索引名稱中的數字部分加 1。
想要了解更多?
- 客户端 Maven 地址: https://mvnrepository.com/artifact/com.infinilabs/easysearch-client/2.0.2
- 更詳細的文檔和示例代碼在 官網 持續更新中,請隨時關注!
大家有啥問題或者建議,也歡迎隨時反饋!
關於 Easysearch
INFINI Easysearch 是一個分佈式的搜索型數據庫,實現非結構化數據檢索、全文檢索、向量檢索、地理位置信息查詢、組合索引查詢、多語種支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同時添加和完善多項企業級功能。Easysearch 助您擁有簡潔、高效、易用的搜索體驗。
官網文檔:https://infinilabs.cn/docs/latest/easysearch
作者:張磊,極限科技(INFINI Labs)搜索引擎研發負責人,對 Elasticsearch 和 Lucene 源碼比較熟悉,目前主要負責公司的 Easysearch 產品的研發以及客户服務工作。