Spring Boot 整合Elasticsearch實現簡單查詢

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第18天,點選檢視活動詳情

背景

專案中我們經常會用搜索功能,普通的搜尋我們可以用一個SQL的like也能實現匹配,但是搜尋的核心需求是全文匹配,對於全文匹配,資料庫的索引是根本派不上用場的,那隻能全表掃描。全表掃描的速度已經非常慢了,還需要在每條記錄上做全文匹配,一個字一個字的比對,導致查詢的資料更慢。所以,使用資料來做搜尋,效能上完全沒法滿足要求。所以我們需要採用Elasticsearch來實現檢索,本文將介紹SpringBoot如何整合Elasticsearch?

系統整合

引入jar包

``` org.springframework.boot spring-boot-starter-web

org.springframework.boot spring-boot-starter-data-elasticsearch ```

application.yml檔案中新增ES配置

elasticsearch: rest: uris: http://localhost:9200 注意:不同的ES版本,引入jar包和配送屬性檔案的方式不同,本文采用的是Spring Boot 2.3.3+Elasticsearch7.0的版本。

建立文件實體

``` @Document(indexName = "product", createIndex = true) public class Product implements Serializable { private static final long serialVersionUID = -2408117939493050954L;

@Id
@Field(type = FieldType.Text)
private String id;

@Field(type = FieldType.Text)
private String skuNo;

@Field(type = FieldType.Text)
private String tilte;

@Field(type = FieldType.Double)
private BigDecimal price;

@Field(type = FieldType.Date, format = DateFormat.basic_date_time)
private Date createDate;

}
``` 說明: - indexName:索引的名稱 - createIndex:ture表示如果不存在,則建立 - @Id:索引id - @Field:type欄位的型別,format:查詢出時間格式化型別。

介面實現

public interface EsProductRepository extends ElasticsearchRepository<Product,String> { List<Product> findByskuNoAndTilte(String sku,String title); } 說明:整合ElasticsearchRepository介面,採用的是JPA的方式實現,JPA預設提供了相關的介面實現。

具體實現

Elasticsearch的實現分為基礎查詢和DSL查詢。

基礎查詢

基礎查詢主要包含的CRUD查詢,以及一些模糊、範圍查詢等。

新增文件

請求引數

{      "id":"5",      "skuNo":"sku0005",      "tilte":"紅樓夢",       "price":"93.37",       "createDate":"1514736000000" }

說明:date型別傳入的引數為long型別。

Controller實現

@PostMapping("/addProduct") public Result addProduct(@RequestBody Product product) { esProductRepository.save(product); Result result = new Result(); result.setCode(200); result.setData(product); return result; }

返回結果

{ "data": { "id": "5", "skuNo": "sku0005", "tilte": "紅樓夢", "price": 93.37, "createDate": "2017-12-31T16:00:00.000+00:00" }, "code": 200, "msg": null }

修改文件

修改與新增基本相同,唯一區別為:請求引數傳入的Id,如果存在則為修改,否則為新增。

通過id查詢文件資訊

#### Controller實現 @GetMapping("/getProductById") public Result getProductById(@RequestParam String id) { Optional<Product> product = esProductRepository.findById(id); return Result.success(product); }

刪除文件

#### Controller實現 @PostMapping("/deleteById") public Result deleteById(@RequestParam String id) { return Result.success(null); }

分頁查詢

Controller實現

@GetMapping("/getPageList") public Result getPageList(@RequestParam int pageNum,@RequestParam int pageSize) { Pageable pageable = PageRequest.of(pageNum, pageSize); Page<Product> pageList= esProductRepository.findAll(pageable); return Result.success(pageList); }

返回結果

{ "data": { "content": [ { "id": "1", "skuNo": "p0001", "tilte": null, "price": 99.9, "createDate": null }, { "id": "3", "skuNo": "p0002", "tilte": null, "price": 99.8, "createDate": null }, { "id": "4", "skuNo": "p0004", "tilte": null, "price": 110, "createDate": null }, { "id": "L1zuVYEBuycvlc7eiQ7_", "skuNo": "sku0001", "tilte": "水滸傳", "price": 93.37, "createDate": "1970-01-01T05:37:00.611+00:00" }, { "id": "5", "skuNo": "sku0005", "tilte": "紅樓夢", "price": 93.37, "createDate": "2017-12-31T16:00:00.000+00:00" } ], "pageable": { "sort": { "sorted": false, "unsorted": true, "empty": true }, "offset": 0, "pageSize": 5, "pageNumber": 0, "paged": true, "unpaged": false }, "aggregations": null, "scrollId": null, "maxScore": 1.0, "totalPages": 1, "totalElements": 5, "number": 0, "size": 5, "sort": { "sorted": false, "unsorted": true, "empty": true }, "numberOfElements": 5, "first": true, "last": true, "empty": false }, "code": 200, "msg": null } 說明: - totalPages:總頁數 - totalElements:總記錄數

模糊查詢

#### Controller實現 @GetMapping("/findByTilteLike") public Result findByTilteLike(@RequestParam String key) { List<Product> products = esProductRepository.findByTilteLike(key); return Result.success(products); } 說明:模糊查詢通過findByxxlike

範圍查詢

範圍查詢通常是指>、< >= <=等

Controller實現

@GetMapping("/findByPriceGreaterThanEqual") public Result findByPriceGreaterThanEqual(@RequestParam Double price) { List<Product> products = esProductRepository.findByPriceGreaterThanEqual(price); return Result.success(products); } 說明:範圍查詢通過findByxxGreaterThanEqual - 大於:GreaterThan - 大於等於:GreaterThanEqual - 小於:LessThan - 小於等於:LessThanEqual

總結

本文講解了Spring Boot整合Elasticsearch採用的是ES模板的方式實現基礎查詢,關於相關的高階查詢將在一下章進行講解,如有疑問請隨時反饋。