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,别拿它当数据库用。
无关技术的奇怪姿势
科普一些无关技术的奇怪的姿势,多学点东西总归是有用的吧。
智和德
- 智:是指抛开利益、权利去思考问题。这可能不是此刻解决问题的最优解,但这样做可以得到最接近真理的答案,是寻找真理的最有效方法。
- 德:世界上不可能每个人都和你思想一致,做到理解和包容别人的思想就是德。
利用智和德去看待美国现在的种族歧视,去思考他们左派(民主党)和右派(共和党)的思想,真能受益匪浅。