一個基於ElasticSearchRestTemplate的增刪改查的例子
阿新 • • 發佈:2021-12-13
現在網上的用springboot對ElasticSearch做增刪改查的文章,幾乎都是用的原生API或者繼承了ElasticsearchRepository去做。但是現在我用的springboot2.5.6已經移除了ElasticsearchRepository裡的search()方法,只剩了一些特別基礎的增刪改查,基本上是不能用的。官方明顯是想讓開發者用ElasticsearchRestTemplate去做,但是搜尋網上沒有發現很好的增刪改查教程,於是我把自己寫的程式碼貼一下:
package com.markerhub.search.model.mq; import com.alibaba.fastjson.JSON; import com.markerhub.config.RabbitConfig; import com.markerhub.entity.Blog; import com.markerhub.search.model.BlogPostDocument; import com.markerhub.service.BlogService; import com.markerhub.util.MyUtils; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.core.query.UpdateResponse; import org.springframework.stereotype.Component; @Slf4j @Component @RabbitListener(queues = RabbitConfig.ES_QUEUE) public class MQMessageHandler { BlogService blogService; @Autowired public void setBlogService(BlogService blogService) { this.blogService = blogService; } ElasticsearchRestTemplate elasticsearchRestTemplate; @Autowired public void setElasticsearchRestTemplate(ElasticsearchRestTemplate elasticsearchRestTemplate) { this.elasticsearchRestTemplate = elasticsearchRestTemplate; } @SneakyThrows @RabbitHandler public void handler(PostMQIndexMessage message) { switch (message.getType()) { case PostMQIndexMessage.UPDATE: Long updateId = message.getPostId(); Blog blogExisted = blogService.getById(updateId); BlogPostDocument postDocument = MyUtils.blogToDocument(blogExisted); String obj = JSON.toJSONString(postDocument); Document document = Document.parse(obj); UpdateQuery query = UpdateQuery .builder(String.valueOf(updateId)) .withDocument(document) .build(); IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(BlogPostDocument.class); UpdateResponse update = elasticsearchRestTemplate.update(query, indexCoordinates); String result = String.valueOf(update.getResult()); log.info("更新結果: {}", result); break; case PostMQIndexMessage.REMOVE: Long deleteId = message.getPostId(); String delete = elasticsearchRestTemplate.delete(deleteId.toString(), BlogPostDocument.class); log.info("刪除結果: {}", delete); break; case PostMQIndexMessage.CREATE: Long createId = message.getPostId(); Blog newBlog = blogService.getById(createId); BlogPostDocument newDocument = MyUtils.blogToDocument(newBlog); BlogPostDocument save = elasticsearchRestTemplate.save(newDocument); log.info("儲存結果: {}", save); break; default: log.error("沒找到對應的訊息型別: {}", message); } } }
上面是對rabbitmq整合時當資料庫更新,往佇列發一條訊息,發訊息的程式碼沒有貼出來,不過重點不在這裡。這裡通知消費者去執行相關的方法。首先ElasticsearchRestTemplate把增刪改查分開了,增是增,刪是刪,改是改,查是查,不能再把增改一起用了。實現比較簡單,程式碼也比較直白,查詢程式碼是這樣的:
/** * 搜尋功能,從es搜尋 */ @GetMapping("/search/{currentPage}") public Result search(@PathVariable Integer currentPage, @RequestParam String keyword) { MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, "title", "description", "content"); NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder() .withQuery(multiMatchQueryBuilder) .withSort(SortBuilders.fieldSort("created").order(SortOrder.DESC)) .build(); SearchHits<BlogPostDocument> search = elasticsearchRestTemplate.search(nativeSearchQuery, BlogPostDocument.class); if (search.getTotalHits() == 0) { throw new ResourceNotFoundException("沒有相關記錄"); } // List<SearchHit<BlogPostDocument>> list = search.getSearchHits(); ArrayList<BlogPostDocument> list = new ArrayList<>(); for (SearchHit<BlogPostDocument> hit : search.getSearchHits()) { list.add(hit.getContent()); } Page<BlogPostDocument> page = MyUtils.listToPage(list, currentPage, 5); return Result.succ(page); } @GetMapping("/searchByYear/{currentPage}/{year}") public Result searchByYear(@PathVariable Integer currentPage, @RequestParam String keyword, @PathVariable Integer year) { MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, "title", "description", "content"); NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.boolQuery() .must(QueryBuilders.rangeQuery("created").gte(year + "-01-01T00:00:00").lte(year + "-12-31T23:59:59") .includeUpper(true) .includeLower(true)) .must(multiMatchQueryBuilder)) .withSort(SortBuilders.fieldSort("created").order(SortOrder.DESC)) .build(); SearchHits<BlogPostDocument> search = elasticsearchRestTemplate.search(nativeSearchQuery, BlogPostDocument.class); if (search.getTotalHits() == 0) { throw new ResourceNotFoundException("沒有相關記錄"); } ArrayList<BlogPostDocument> list = new ArrayList<>(); for (SearchHit<BlogPostDocument> hit : search.getSearchHits()) { list.add(hit.getContent()); } Page<BlogPostDocument> page = MyUtils.listToPage(list, currentPage, 5); return Result.succ(page); }
總體來看,ElasticsearchRestTemplate的應用方法是,先構建相應的query物件(MultiMatchQueryBuilder或者UpdateQuery之類的),在這個物件裡傳入你的查詢條件或者修改的物件或者新增的物件,再傳入ElasticsearchRestTemplate的相關方法裡。
本文來自部落格園,作者:imissinstagram,轉載請註明原文連結:https://www.cnblogs.com/LostSecretGarden/p/15685055.html