Elasticsearch基本概念
Elasticsearch有四種構成存儲空間的基本結構:Indices、Types、Documents、Fields。
將這四種結構和關係型數據庫對比,能更好說明它們是什麼:
- Indices看作Database(數據庫);
- Types看作Tables(表);
- Documents看作Rows(行);
- Fields看作Columns(列)。
選擇操作ES的客戶端
官方提供很多操作ES的客戶端,比如:
- Transport Client
- High Level REST Client
- 更多客戶端詳細信息可以去Spring Data Elasticsearch查看。如果你沒那麼多時間,本文可以讓你快速學會,在Spring中對ES增刪改查和條件分頁查詢的簡單操作。
本文使用High Level REST Client對ES增刪改查。因爲這是官方強烈推薦的。
Gradle引入High Level REST Client依賴
Gradle中引入依賴:
implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.4.2'
Java 實例
依賴注入Bean
@Autowired
private RestHighLevelClient restHighLevelClient;
插入
IndexRequest request = new IndexRequest("order")
.id(data.roundId)
.source(gson.toJson(data), XContentType.JSON);
restHighLevelClient.index(request, RequestOptions.DEFAULT);
IndexRequest("order")
,表示index名;id(data.roundId)
,表示document名字;source(gson.toJson(data), XContentType.JSON)
,表示存入data對象轉json的字符串。
刪除
DeleteRequest deleteRequest = new DeleteRequest("order", data.roundId);
restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
更新
UpdateRequest updateRequest = new UpdateRequest("order", data.roundId)
.doc(gson.toJson(data), XContentType.JSON);
restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
查詢(條件分頁)
SearchRequest request = new SearchRequest("order");
request.source(
new SearchSourceBuilder()
.query((QueryBuilder) QueryBuilders.boolQuery()
.must(()->{
if(path != null){
QueryBuilders.termQuery(String.valueOf(Player.class.getField("name")), ip);
}
}
)
.must(
// 如有多個條件,添加參照上個 must
)
)
.sort(JsonUtils.class.getField("inTime"), SortOrder.DESC)
.size(limit)
.from(offset)
);
SearchHits hits = restHighLevelClient.search(request, RequestOptions.DEFAULT).getHits();
long total = hits.getTotalHits().value;
List<Player> result = null;
Stream.of(hits.getHits()).forEach(y -> result.add( gson.fromJson(y.getSourceAsString(), Player.class) ));
must()
表示查詢條件,還有should()
、mustNot()
等,must
裏的lambda表達式表示有值的時候才查詢,更方便根據前端傳入的參數進行條件查詢。limit
爲前端傳入參數,表示查多少個。offset
爲前端傳入參數,表示從哪裏開始查。
Kotlin 實例
依賴注入Bean
@Autowired
lateinit var restHighLevelClient: RestHighLevelClient
插入
val request = IndexRequest("order")
.id(data.roundId)
.source(gson.toJson(data), XContentType.JSON)
restHighLevelClient.index(request, RequestOptions.DEFAULT)
IndexRequest("order")
,表示index名;id(data.roundId)
,表示document名字;source(gson.toJson(data), XContentType.JSON)
,表示存入data對象轉json的字符串。
刪除
val deleteRequest = DeleteRequest("order", roomPlayer.roomId.toString() + "rpl" + roomPlayer.playerId)
restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT)
更新
val updateRequest = UpdateRequest("order", data.orderId)
.doc(gson.toJson(data), XContentType.JSON)
restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT)
查詢(條件分頁)
inline fun <T> T.applyIf(validate: Boolean, block: T.() -> Unit): T {
if (validate) {
block()
}
return this
}
val request = SearchRequest("order")
request.source(
SearchSourceBuilder()
.query(QueryBuilders.boolQuery()
.applyIf(startTime != null && endTime != null) {
must(
QueryBuilders.rangeQuery(MainVisitRecordPO::inTime.name)
.gte(startTime!! * 1000)
.lte(endTime!! * 1000)
)
}
.applyIf(ip != null) {
must(
QueryBuilders.termQuery(MainVisitRecordPO::ip.name, ip)
)
}
)
.sort(MainVisitRecordPO::inTime.name, SortOrder.DESC)
.size(pageable.limit)
.from(pageable.offset)
)
val hits = restHighLevelClient.search(request, RequestOptions.DEFAULT).hits
val total = hits.totalHits?.value?:0
val result = hits.hits.map { gson.fromJson(it.sourceAsString, MainVisitRecordPO::class.java) }
must()
表示查詢條件,還有should()
、mustNot()
等,must
裏的lambda表達式表示有值的時候才查詢,更方便根據前端傳入的參數進行條件查詢。limit
爲前端傳入參數,表示查多少個。offset
爲前端傳入參數,表示從哪裏開始查。
注意
對Elasticsearch增、刪、改的操作,並不是實時的。也就是更改A
數據後立刻查詢A
數據,得到的結果依舊是未更新的A
數據。
需要立刻更新ES需要使用setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
設置,比如更新操作:
val updateRequest = UpdateRequest("order", data.orderId)
.doc(gson.toJson(data), XContentType.JSON)
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
這樣會對ES性能影響,所以並不推薦使用ES做業務,來儘量規避這類問題。
所以ES終究是ES,別拿它當數據庫用。
無關技術的奇怪姿勢
科普一些無關技術的奇怪的姿勢,多學點東西總歸是有用的吧。
智和德
- 智:是指拋開利益、權利去思考問題。這可能不是此刻解決問題的最優解,但這樣做可以得到最接近真理的答案,是尋找真理的最有效方法。
- 德:世界上不可能每個人都和你思想一致,做到理解和包容別人的思想就是德。
利用智和德去看待美國現在的種族歧視,去思考他們左派(民主黨)和右派(共和黨)的思想,真能受益匪淺。