- 1.引入pom依賴
- 2.application 配置
- 3.JavaBean配置以及ES相關注解
-
- 3.1 Student實體類
- 3.2 Teacher實體類
- 3.3 Headmaster 實體類
- 4. 啟動類配置
- 5.elasticsearchRestTemplate 新增
-
- ==5.1 createIndex && putMapping 創建索引及映射==
-
- 5.1.1 Controller層
- 5.1.2 service層
- 5.1.3 serviceimpl層
- createIndex && putMapping 創建索引及映射測試結果:
- ==5.2 save 添加文檔==
-
- 5.2.1 Controller層
- 5.2.2 service層
- 5.2.3 serviceimpl層
- save 添加文檔測試結果:
- 6.elasticsearchRestTemplate 刪除
-
- ==6.1 deleteIndex 刪除索引==
-
- 6.1.1 Controller層
- 6.1.2 service層
- 6.1.3 serviceimpl層
- deleteIndex 刪除索引測試結果:
- ==6.2 delete 刪除文檔(通過主鍵刪除)==
-
- 6.2.1 Controller層
- 6.2.2 service層
- 6.2.3 serviceimpl層
- delete(通過主鍵刪除) 刪除文檔測試結果:
- ==6.3 delete 刪除文檔(刪除通過query所搜索到的所有數據)==
-
- 6.3.1 Controller層
- 6.3.2 service層
- 6.3.3 serviceimpl層
- delete(刪除通過query所搜索到的所有數據) 刪除文檔測試結果:
- 7.elasticsearchRestTemplate 修改
-
- ==7.1 update 修改文檔(根據主鍵修改)==
-
- 7.1.1 Controller層
- 7.1.2 service層
- 7.1.3 serviceimpl層
- update 修改文檔(根據主鍵修改)測試結果:
- 8.elasticsearchRestTemplate 查詢
-
- ==8.1 get 查詢文檔(根據主鍵查詢)==
-
- 8.1.1 Controller層
- 8.1.2 service層
- 8.1.3 serviceimpl層
- get 查詢文檔(根據主鍵查詢)測試結果:
- ==8.2 exists 查詢文檔(判斷主鍵id是否存在)==
-
- 8.2.1 Controller層
- 8.2.2 service層
- 8.2.3 serviceimpl層
- exists 查詢文檔(判斷主鍵id是否存在)測試結果:
- ==8.3 queryForPage 查詢文檔(分頁查詢)==
-
- 8.3.1 Controller層
- 8.3.2 service層
- 8.3.3 serviceimpl層
- queryForPage 查詢文檔(分頁查詢)測試結果:
- ==8.4 AnalyzeRequest (根據入參內容返回分詞后結果)==
-
- 8.4.1 Controller層
- 8.4.2 service層
- 8.4.3 serviceimpl層
- AnalyzeRequest (根據入參內容返回分詞后結果)測試結果:
- ==8.5 termQuery 查詢文檔(入參不分詞,精確匹配)==
-
- 8.5.1 Controller層
- 8.5.2 service層
- 8.5.3 serviceimpl層
- termQuery 查詢文檔(入參不分詞,精確匹配)測試結果:
- ==8.6 match 查詢文檔(會對查詢條件進行分詞)==
-
- 8.6.1 Controller層
- 8.6.2 service層
- 8.6.3 serviceimpl層
- match 查詢文檔(會對查詢條件進行分詞)測試結果:
- ==8.7 matchAllQuery 查詢文檔(查詢此索引下所有文檔)==
-
- 8.7.1 Controller層
- 8.7.2 service層
- 8.7.3 serviceimpl層
- matchAllQuery 查詢文檔(查詢此索引下所有文檔)測試結果:
- ==8.8 wildcardQuery 查詢文檔(模糊查詢)==
-
- 8.8.1 Controller層
- 8.8.2 service層
- 8.8.3 serviceimpl層
- wildcardQuery 查詢文檔(模糊查詢)測試結果:
- ==8.9 prefixQuery 查詢文檔(前綴查詢)==
-
- 8.9.1 Controller層
- 8.9.2 service層
- 8.9.3 serviceimpl層
- prefixQuery 查詢文檔(前綴查詢)測試結果:
- ==8.10 regexpQuery 查詢文檔(正則表達式查詢)==
-
- 8.10.1 Controller層
- 8.10.2 service層
- 8.10.3 serviceimpl層
- regexpQuery 查詢文檔(正則表達式查詢) 測試結果:
- ==8.11 rangeQuery 查詢文檔(范圍查詢)==
-
- 8.11.1 Controller層
- 8.11.2 service層
- 8.11.3 serviceimpl層
- rangeQuery 查詢文檔(范圍查詢) 測試結果:
- ==8.12 Sort 查詢文檔 (排序)==
-
- 8.12.1 Controller層
- 8.12.2 service層
- 8.12.3 serviceimpl層
- Sort 查詢文檔 (排序) 測試結果:
- ==8.13 queryStringQuery 查詢文檔 (多條件查詢 一值多域)==
-
- 8.13.1 Controller層
- 8.13.2 service層
- 8.13.3 serviceimpl層
- queryStringQuery 查詢文檔 (多條件查詢 一值多域) 測試結果:
- ==8.14 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must)==
-
- 8.14.1 Controller層
- 8.14.2 service層
- 8.14.3 serviceimpl層
- boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must) 測試結果:
- ==8.15 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:filter)==
-
- 8.15.1 Controller層
- 8.15.2 service層
- 8.15.3 serviceimpl層
- boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:filter) 測試結果:
- ==8.16 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must_not)==
-
- 8.16.1 Controller層
- 8.16.2 service層
- 8.16.3 serviceimpl層
- boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must_not) 測試結果:
- ==8.17 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:should)==
-
- 8.17.1 Controller層
- 8.17.2 service層
- 8.17.3 serviceimpl層
- boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:should) 測試結果:
- ==8.18 HighlightBuilder 查詢文檔 (高亮)==
-
- 8.18.1 Controller層
- 8.18.2 service層
- 8.18.3 serviceimpl層
- HighlightBuilder 查詢文檔 (高亮) 測試結果:
- ==8.19 AggregationBuilders 查詢文檔 (聚合查詢)==
-
- 8.19.1 Controller層
- 8.19.2 service層
- 8.19.3 serviceimpl層
- AggregationBuilders 查詢文檔 (聚合查詢) 測試結果:
- ==8.20 SuggestBuilders查詢文檔 (completionSuggestion---搜索建議補全)==
-
- 8.20.1 Controller層
- 8.20.2 service層
- 8.20.3 serviceimpl層
- SuggestBuilders查詢文檔 (completionSuggestion---搜索建議補全) 測試結果:
- ==8.21 SuggestBuilders查詢文檔 (termSuggestion---糾錯補全)==
-
- 8.21.1 Controller層
- 8.21.2 service層
- 8.21.3 serviceimpl層
- SuggestBuilders查詢文檔 (termSuggestion---糾錯補全) 測試結果:
- ==~~8.22 SuggestBuilders查詢文檔 (phraseSuggestion---糾錯補全)~~==
-
- ~~8.22.1 Controller層~~
- ~~8.22.2 service層~~
- ~~8.22.3 serviceimpl層~~
- ~~SuggestBuilders查詢文檔 (termSuggestion---糾錯補全) 測試結果:~~
- 鏈接:[windows版本 Elasticsearch服務端-7.4.0以及kibana-7.4.0和ik分詞器下載地址](https://mp.csdn.net/mp_download/manage/download/UpDetailed)
-
1.引入pom依賴
- 主要引用 elasticsearch使用相關依賴
- 注意ES 服務端版本(7.4.0)要與客戶端版本相容
- 注意 hutool的工具類 實體轉map 版本
<!--引入springboot父工程依賴--><!--引入依賴作用:可以省去version標簽來獲得一些合理的默認配置--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version></parent><dependencies><!--elasticsearch使用相關依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><!--引入提供Web開發場景依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--這里用到了類型轉Map,這里用到hutool的工具類(版本高一些,低版本的 如果傳的就是Map類型,在map轉map時會報錯)--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>5.7.13</version></dependency><!--用@Data 減少JavaBean get...set...方法--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--兩個用來做測試的jar包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies>
2.application 配置
spring:elasticsearch:rest:uris: 127.0.0.1:9200 #---ES的連接地址,多個地址用逗號分隔username: #---用戶名password: #---密碼connection-timeout: 1000 #---連接超時時間(默認1s)read-timeout: 1000 #---讀取超時時間(默認30s)
?3.JavaBean配置以及ES相關注解
- 注解:@Document用來聲明Java對象與ElasticSearch索引的關系
???????????? indexName 索引名稱(是字母的話必須是小寫字母)
???????????? type 索引類型
???????????? shards 主分區數量,默認5
???????????? replicas 副本分區數量,默認1
???????????? createIndex 索引不存在時,是否自動創建索引,默認true
????????????????????????不建議自動創建索引(自動創建的索引 是按著默認類型和默認分詞器) - 注解:@Id 表示索引的主鍵
- 注解:@Field 用來描述字段的ES數據類型,是否分詞等配置,等于Mapping描述
???????????? index 設置字段是否索引,默認是true,如果是false則該字段不能被查詢
???????????? store 默認為no,被store標記的fields被存儲在和index不同的fragment中,以便于快速檢索。雖然store占用磁盤空間,但是減少了計算。
???????????? type 數據類型(text、keyword、date、object、geo等)
???????????? analyzer 對字段使用分詞器,注意一般如果要使用分詞器,字段的type一般是text。
???????????? format 定義日期時間格式,詳細見 官方文檔:?format | Elasticsearch Guide [8.9] | Elastic. - 注解:@CompletionField 定義關鍵詞索引 要完成補全搜索
???????????? analyzer 對字段使用分詞器,注意一般如果要使用分詞器,字段的type一般是text。
???????????? searchAnalyzer 顯示指定搜索時分詞器,默認是和索引是同一個,保證分詞的一致性。
???????????? maxInputLength:設置單個輸入的長度,默認為50 UTF-16 代碼點
常用數據類型:
簡單類型:-
字符串類型: - string(不再支持)可知string類型的field已經被移除了, 我們需要用text或keyword類型來代替string.
??????????????????? text:會分詞,不支持聚合
??????????????????? keyword:不會分詞,將全部內容作為一個詞條,支持聚合 -
數字類型: 盡可能選擇范圍小的數據類型, 字段的長度越短, 索引和搜索的效率越高;(優先考慮使用帶縮放因子的浮點類型)
??????????????? byte :??????????? 有符號的8位整數, 范圍: [-128 ~ 127]
??????????????? short :?????????? 有符號的16位整數, 范圍: [-32768 ~ 32767]
??????????????? integer : ???????有符號的32位整數, 范圍: [?231?~ 231-1]
??????????????? long :??????????? 有符號的64位整數, 范圍: [?263?~ 263-1]
??????????????? float : ????????????32位單精度浮點數
??????????????? double : ????????64位雙精度浮點數
??????????????? half_float : ????16位半精度IEEE 754浮點類型
??????????????? scaled_float : 縮放類型的的浮點數, 比如price字段只需精確到分, 57.34縮放因子為100,?存儲結果為5734 -
日期類型:date JSON沒有日期數據類型, 所以在ES中, 日期可以是:
??—???包含格式化日期的字符串 “2018-10-01”, 或"2018/10/01 12:10:30" ?? (可以通過 format屬性 定義日期時間格式)DateFormat 官方文法.
??—???代表時間毫秒數的長整型數字.
??—???代表時間秒數的整數. -
布爾類型: boolean 可以接受表示真、假的字符串或數字:
? — ?真值: true, “true”, “on”, “yes”, “1”…
? — ?假值: false, “false”, “off”, “no”, “0”, “”(空字符串), 0.0, 0
復雜類型:
- 數組[]: 由數組中第一個非空值決定數組類型(type = FieldType.Keyword)
- List集合: 由數組中第一個非空值決定數組類型(type = FieldType.Keyword)
- 嵌套類型: list里泛型是object形式的或自定義對象(type = FieldType.Nested)
- 對象:{ }object for single JSON objects 單個JSON對象(type = FieldType.Object)
?3.1 Student實體類
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType;import java.util.Date; import java.util.List;/** 學生* */ @Data @AllArgsConstructor @NoArgsConstructor //indexName名字如果是字母那么必須是小寫字母 @Document(indexName = "student", type = "_doc", replicas = 1, shards = 1, createIndex = true) public class Student {@Id@Field(index = true, store = true, type = FieldType.Keyword)private String sId;@Field(index = true, store = true, type = FieldType.Keyword)private String sName;@Field(index = true, store = true, type = FieldType.Text, analyzer = "ik_smart")//Text可以分詞 ik_smart=粗粒度分詞 ik_max_word 為細粒度分詞private String sAddress;@Field(index = false, store = true, type = FieldType.Integer)private Integer sAge;@Field(index = false, store = true, type = FieldType.Date, format = DateFormat.basic_date_time)private Date sCreateTime;@Field(index = false, store = true, type = FieldType.Object)private Headmaster sHeadmaster;//班主任@Field(index = true, store = false, type = FieldType.Keyword)private String[] sCourseList; //數組類型 由數組中第一個非空值決定(這里數組和集合一個意思了)@Field(index = true, store = false, type = FieldType.Keyword)private List<String> sColorList; //集合類型 由數組中第一個非空值決定@Field(index = true, store = false, type = FieldType.Nested)//嵌套類型list里泛型是object形式的或自定義對象private List<Teacher> sTeacherList; //教所有科目的老師}
?3.2 Teacher實體類
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.core.completion.Completion;import java.util.Date;/** 科目老師* */ @Data @NoArgsConstructor @AllArgsConstructor @Document(indexName = "teacher", type = "_doc", replicas = 1, shards = 1, createIndex = true) public class Teacher {//主鍵id@Id@Field(index = true, store = true, type = FieldType.Keyword)//index:設置通過這個字段是否可以進行搜索private String tId;//姓名@Field(index = true, store = true, type = FieldType.Keyword)private String tName;//英文姓名@Field(index = true, store = true, type = FieldType.Keyword)private String tEnglishName;//班級@Field(index = true, store = true, type = FieldType.Keyword)private String tClassName;//地址@Field(index = true, store = true, type = FieldType.Text, analyzer = "ik_smart")private String tAddress;//至理名言@Field(index = true, store = true, type = FieldType.Keyword)private String tFamous;//年齡@Field(index = true, store = true, type = FieldType.Integer)private Integer tAge;//日期@Field(index = true, store = true, type = FieldType.Date, format = DateFormat.basic_date_time)private Date tCreateTime;//定義關鍵詞索引 要完成補全搜索,必須要用到特殊的數據類型completion,//要漢字拼音都能補全,必須要使用自定義的ik+pinyin分詞器// maxInputLength:設置單個輸入的長度,默認為50 UTF-16 代碼點@CompletionField(analyzer = "ik_smart", searchAnalyzer = "ik_smart", maxInputLength = 100)private Completion completion;public Teacher(String tId, String tName, String tEnglishName, String tClassName, String tAddress, Integer tAge, Date tCreateTime) {this.tId = tId;this.tName = tName;this.tEnglishName = tEnglishName;this.tClassName = tClassName;this.tAddress = tAddress;this.tAge = tAge;this.tCreateTime = tCreateTime;} }
?3.3 Headmaster 實體類
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import java.util.Date; import java.util.List;/** 班主任* */ @Data @NoArgsConstructor @AllArgsConstructor @Document(indexName = "headmaster", type = "_doc", replicas = 1, shards = 1, createIndex = true) public class Headmaster {@Field(index = true, store = false, type = FieldType.Keyword)private String hId;@Field(index = true, store = false, type = FieldType.Keyword)private String hName;@Field(index = true, store = false, type = FieldType.Keyword)private String hAddress;@Field(index = false, store = false, type = FieldType.Integer)private Integer hSalary;@Field(index = false, store = false, type = FieldType.Keyword)private List<String> hClass;@Field(index = true, store = true, type = FieldType.Date, format = DateFormat.basic_date_time)private Date hCreateTime; }
?4. 啟動類配置
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;/** 搜索引擎客戶端啟動類* */ @SpringBootApplication public class ElasticsearchApplication {public static void main(String[] args) {SpringApplication.run(ElasticsearchApplication.class, args);} }
?5.elasticsearchRestTemplate 新增
-
5.1 createIndex && putMapping 創建索引及映射
-
- createIndex :新增索引(數據庫)
- putMapping :新增映射(表結構)
- 一定要通過這種方法創建,否則創建出來的映射都是默認的
createIndex && putMapping 創建索引及映射測試
- 入參classType : 對象是要被ES注解所引用的的(基于@Field和@Documen注解屬性 創建索引和映射)
-
5.1.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSaveService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 新增類*/ @RestController @RequestMapping("/elasticSearch/save") public class ElasticsearchSaveController {@Autowiredprivate ElasticsearchSaveService elasticsearchSaveService;/*** @param classType : 要創建es的索引及映射(一定要通過這種方法創建,否則都是創建出來的映射都是默認的)基于傳入對象中的@Document注解* @return boolean* @throws* @Author Mhh* @Date 2021/12/9 10:43*/@PostMapping("createIndexAndMapping")public boolean createIndexAndMapping(Class<?> classType) {return elasticsearchSaveService.createIndexAndMapping(classType);}}
?5.1.2 service層
/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 新增*/ public interface ElasticsearchSaveService {/*** @param classType : 要創建es的索引及映射(一定要通過這種方法創建,否則都是創建出來的映射都是默認的)基于傳入對象中的@Document注解* @return boolean* @throws* @Author Mhh* @Date 2021/12/9 10:43*/boolean createIndexAndMapping(Class<?> classType); }
?5.1.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSaveService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.stereotype.Service;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 新增*/ @Service public class ElasticsearchSaveServiceImp implements ElasticsearchSaveService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param classType : 要創建es的索引及映射(一定要通過這種方法創建,否則都是創建出來的映射都是默認的)基于傳入對象中的@Document注解* @return boolean* @throws* @Author Mhh* @Date 2021/12/9 10:43*/@Overridepublic boolean createIndexAndMapping(Class<?> classType) {if (elasticsearchRestTemplate.indexExists(classType))return true;boolean index = elasticsearchRestTemplate.createIndex(classType);boolean mapping = elasticsearchRestTemplate.putMapping(classType);return index && mapping;} }
?createIndex && putMapping 創建索引及映射測試結果:
- 根據入參對象 ES注解 創建索引及映射
import com.it.mhh.elasticsearch.controller.ElasticsearchSaveController; import com.it.mhh.elasticsearch.entity.Headmaster; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.test.context.junit4.SpringRunner; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 測試*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSaveControllerTest {@Autowiredprivate ElasticsearchSaveController elasticsearchSaveController;/*** @param classType : 要創建es的索引及映射(一定要通過這種方法創建,否則都是創建出來的映射都是默認的)基于傳入對象中的@Document注解* @return boolean* @throws* @Author Mhh* @Date 2021/12/9 10:43*/@Testpublic void createIndexAndMapping() {boolean indexAndMapping = elasticsearchSaveController.createIndexAndMapping(Student.class);System.err.println(indexAndMapping);}}
- 根據入參對象 ES注解 創建索引及映射
-
5.2 save 添加文檔
-
- save(Iterable entities):可傳集合 批量添加(同種類對象集合)
- save(T entity) :單個對象
- save(T… entities) : 可變參
save 添加文檔測試
- 入參entities :有重載 可傳集合 單個 或者 可變參
-
5.2.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSaveService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 新增類*/ @RestController @RequestMapping("/elasticSearch/save") public class ElasticsearchSaveController {@Autowiredprivate ElasticsearchSaveService elasticsearchSaveService;/*** @param entities : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/@PostMapping("saveList")public <T> Iterable<T> save(@RequestBody Iterable<T> entities) {return elasticsearchSaveService.save(entities);}/*** @param t : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/@PostMapping("save")public <T> T save(@RequestBody T t) {return elasticsearchSaveService.save(t);}}
?5.2.2 service層
/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 新增*/ public interface ElasticsearchSaveService {/*** @param entities : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/public <T> Iterable<T> save(Iterable<T> entities);/*** @param t : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/public <T> T save(T t); }
?5.2.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSaveService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.stereotype.Service;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 新增*/ @Service public class ElasticsearchSaveServiceImp implements ElasticsearchSaveService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param entities : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/@Overridepublic <T> Iterable<T> save(Iterable<T> entities) {return elasticsearchRestTemplate.save(entities);}/*** @param t : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/@Overridepublic <T> T save(T t) {return elasticsearchRestTemplate.save(t);}}
?save 添加文檔測試結果:
- 根據被ES注解引用的入參對象存入相應索引中
import com.it.mhh.elasticsearch.controller.ElasticsearchSaveController; import com.it.mhh.elasticsearch.entity.Headmaster; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.test.context.junit4.SpringRunner; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 測試*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSaveControllerTest {@Autowiredprivate ElasticsearchSaveController elasticsearchSaveController;/*** @param entities : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/@Testpublic void savesStudentES() {Headmaster headmaster = new Headmaster("1", "小白主任", "山東", 7500, Arrays.asList("一班", "二班"), new Date());//班主任List<String> colorList = new ArrayList<>();//顏色colorList.add("red");colorList.add("white");colorList.add("black");List<Teacher> teacherList = new ArrayList<>();//所有科目老師teacherList.add(new Teacher("2", "小黑", "black", "一班", "山東省濟南市歷下區", 13, new Date()));teacherList.add(new Teacher("2", "小藍", "blue", "二班", "山東省菏澤市單縣", 14, new Date()));Student student = new Student("1", "mhh", "濟南", 12, new Date(), headmaster, new String[]{"語文", "數學", "英語"}, colorList, teacherList);Student save = elasticsearchSaveController.save(student);System.out.println(save);}/*** @param entities : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/@Testpublic void savesTeacherES() {Teacher teacher = new Teacher("1", "小黑老師", "black", "一班", "河北省保定市蓮池區", 14, new Date());Teacher save = elasticsearchSaveController.save(teacher);System.out.println(save);}/*** @param entities : 入參對象(必須是被@Document注解注釋的)【入參 可傳單個 T,集合Iterable<T>,可變參 T... 】* @return T 反參對象* @explain : 添加文檔* @Author Mhh* @Date 2021/12/27 10:55*/@Testpublic void savesTeacherListES() {List<Teacher> teacherList = new ArrayList<>();teacherList.add(new Teacher("1", "小黑老師", "black", "一班", "山東省泰安市岱岳區","且隨疾風前行,身后亦須留心", 15, new Date(), new Completion(new String[]{"山東省泰安市岱岳區"})));teacherList.add(new Teacher("2", "小白老師", "white", "二班", "山東省濟南市歷下區", "此劍之勢,愈斬愈烈",17, new Date(), new Completion(new String[]{"山東省濟南市歷下區"})));teacherList.add(new Teacher("3", "小黃老師", "yellow", "二班", "河北省保定市蓮池區", "榮耀存于心,而非流于形",18, new Date(), new Completion(new String[]{"河北省保定市蓮池區"})));teacherList.add(new Teacher("5", "小藍教授", "blue", "二班", "山東省濟南市高新區", "吾之初心,永世不忘",21, new Date(), new Completion(new String[]{"山東省濟南市高新區"})));teacherList.add(new Teacher("4", "小綠教授", "green", "一班", "山西省太原市杏花嶺區", "有些失誤無法犯兩次",24, new Date(), new Completion(new String[]{"山西省太原市杏花嶺區"})));Iterable<Teacher> save = elasticsearchSaveController.save(teacherList);System.out.println(save);}}
?6.elasticsearchRestTemplate 刪除
- 根據被ES注解引用的入參對象存入相應索引中
-
6.1 deleteIndex 刪除索引
-
- deleteIndex :刪除索引(數據庫)
deleteIndex 刪除索引測試
- 入參classType : 刪除的哪個索引(從傳入對象中的@Document注解中indexName屬性獲取)
-
6.1.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchDeleteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 刪除類*/ @RestController @RequestMapping("/elasticSearch/delete") public class ElasticsearchDeleteController {@Autowiredprivate ElasticsearchDeleteService elasticsearchDeleteService;/*** @param clazz : 刪除的哪個索引(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain : 刪除索引* @Author Mhh* @Date 2021/12/27 14:27*/@PostMapping("deleteIndex")public Boolean deleteIndex(Class<?> clazz) {return elasticsearchDeleteService.deleteIndex(clazz);} }
?6.1.2 service層
import org.springframework.data.elasticsearch.core.query.Query; /*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchDeleteService {/*** @param clazz : 刪除的哪個索引(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain : 刪除索引* @Author Mhh* @Date 2021/12/27 14:27*/public Boolean deleteIndex(Class<?> clazz); }
?6.1.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchDeleteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.stereotype.Service;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchDeleteServiceImp implements ElasticsearchDeleteService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param clazz : 刪除的哪個索引(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain : 刪除索引* @Author Mhh* @Date 2021/12/27 14:27*/public Boolean deleteIndex(Class<?> clazz) {return elasticsearchRestTemplate.deleteIndex(clazz);}}
?deleteIndex 刪除索引測試結果:
- 根據入參對象 ES@Document注解中indexName屬性值刪除索引
- 如果刪除的 索引名不存在 返回false
import com.it.mhh.elasticsearch.controller.ElasticsearchDeleteController; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermsQueryBuilder; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.test.context.junit4.SpringRunner;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchDeleteControllerTest {@Autowiredprivate ElasticsearchDeleteController elasticsearchDeleteController;/*** @param clazz : 刪除的哪個索引(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain : 刪除索引* @Author Mhh* @Date 2021/12/27 14:27*/@Testpublic void deleteIndex() {Boolean aBoolean = elasticsearchDeleteController.deleteIndex(Teacher.class);System.err.println(aBoolean);} }
-
6.2 delete 刪除文檔(通過主鍵刪除)
-
- delete(Object entity):通過入參對象主鍵刪除
- delete(String id, Class<?> entityType) id表示要刪除的主鍵,entityType表示 被@Document注解且有indexName屬性值(indexName屬性值為索引名)
delete(通過主鍵刪除) 刪除文檔測試
- 兩種入參形式 都是通過主鍵id刪除,即使入參對象其它屬性設置了值也是通過主鍵id刪除
-
6.2.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchDeleteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 刪除類*/ @RestController @RequestMapping("/elasticSearch/delete") public class ElasticsearchDeleteController {@Autowiredprivate ElasticsearchDeleteService elasticsearchDeleteService;/*** @param id : 要刪除的主鍵id* @param entityType : 刪除的哪個索引的數據(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @throws* @Author Mhh* @Date 2021/12/9 10:40*/@PostMapping("deleteById")public Boolean delete(@RequestParam("id") String id, Class<?> entityType) {return elasticsearchDeleteService.delete(id, entityType);}/*** @param entity : 這個實體對象必須是被@Document注解且有indexName屬性值) 以及主鍵必須有值,其它參數有無都沒關系(和用主鍵id刪除沒區別)* @return java.lang.Boolean* @throws* @Author Mhh* @Date 2021/12/9 10:40*/@PostMapping("delete")public Boolean delete(Object entity) {return elasticsearchDeleteService.delete(entity);}}
?6.2.2 service層
import org.springframework.data.elasticsearch.core.query.Query; /*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchDeleteService {/*** @param id : 要刪除的主鍵id* @param entityType : 刪除的哪個索引的數據(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @throws* @Author Mhh* @Date 2021/12/9 10:40*/Boolean delete(String id, Class<?> entityType);/*** @param entity : 這個實體對象必須是被@Document注解且有indexName屬性值) 以及主鍵必須有值,其它參數有無都沒關系(和用主鍵id刪除沒區別)* @return java.lang.Boolean* @throws* @Author Mhh* @Date 2021/12/9 10:40*/public Boolean delete(Object entity); }
?6.2.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchDeleteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.stereotype.Service;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchDeleteServiceImp implements ElasticsearchDeleteService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param id : 要刪除的主鍵id* @param entityType : 刪除的哪個索引的數據(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @throws* @Author Mhh* @Date 2021/12/9 10:40*/@Overridepublic Boolean delete(String id, Class<?> entityType) {String delete = elasticsearchRestTemplate.delete(id, entityType);return true;}/*** @param entity : 這個實體對象必須是被@Document注解且有indexName屬性值) 以及主鍵必須有值,其它參數有無都沒關系(和用主鍵id刪除沒區別)* @return java.lang.Boolean* @throws* @Author Mhh* @Date 2021/12/9 10:40*/@Overridepublic Boolean delete(Object entity) {String delete = elasticsearchRestTemplate.delete(entity);return true;} }
?delete(通過主鍵刪除) 刪除文檔測試結果:
- 根據入參對象 ES@Document注解中indexName屬性值查詢刪除哪哥索引中文檔
- 如果刪除的指定索引名中的文檔 索引名不存在 報錯
- 即使刪除的文檔不存在 ES依舊返回刪除的主鍵
import com.it.mhh.elasticsearch.controller.ElasticsearchDeleteController; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermsQueryBuilder; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.test.context.junit4.SpringRunner;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchDeleteControllerTest {@Autowiredprivate ElasticsearchDeleteController elasticsearchDeleteController;/*** @param entity : 這個實體對象必須是被@Document注解且有indexName屬性值) 以及主鍵必須有值,其它參數有無都沒關系(和用主鍵id刪除沒區別)* @return java.lang.Boolean* @throws* @Author Mhh* @Date 2021/12/9 10:40*/@Testpublic void deleteByIdES() {Teacher teacher = new Teacher();teacher.setTId("3");teacher.setTName("mhh");//沒有用處,根據主鍵刪除Boolean delete = elasticsearchDeleteController.delete(teacher);//==Boolean aBoolean = elasticsearchDeleteController.delete("3", Teacher.class);System.err.println(aBoolean);//true} }
-
6.3 delete 刪除文檔(刪除通過query所搜索到的所有數據)
-
- delete(Query query, Class<?> clazz, IndexCoordinates index)
??????????query:查詢語法 包含(term查詢、terms查詢、match查詢、范圍查詢、模糊查詢…)
??????????clazz: 來指定查詢字段和結果后返回的實例對象
??????????indx: 指定索引
delete(刪除通過query所搜索到的所有數據) 刪除文檔測試
- 刪除掉被query所搜索到的所有數據。
- delete(Query query, Class<?> clazz, IndexCoordinates index)
-
6.3.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchDeleteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 刪除類*/ @RestController @RequestMapping("/elasticSearch/delete") public class ElasticsearchDeleteController {@Autowiredprivate ElasticsearchDeleteService elasticsearchDeleteService;/*** @param query : 刪除掉被query所搜索到的所有數據。* @param entity : 刪除的哪個索引的數據(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain :* @Author Mhh* @Date 2021/12/27 14:22*/@PostMapping("deleteByQuery")public Boolean delete(Query query, Class<?> entity) {return elasticsearchDeleteService.delete(query, entity);}}
?6.3.2 service層
import org.springframework.data.elasticsearch.core.query.Query; /*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchDeleteService {/*** @param query : 刪除掉被query所搜索到的所有數據。* @param entity : 刪除的哪個索引的數據(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain :* @Author Mhh* @Date 2021/12/27 14:22*/public Boolean delete(Query query, Class<?> entity);}
?6.3.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchDeleteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.stereotype.Service;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchDeleteServiceImp implements ElasticsearchDeleteService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param query : 刪除掉被query所搜索到的所有數據。* @param entity : 刪除的哪個索引的數據(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain :* @Author Mhh* @Date 2021/12/27 14:22*/public Boolean delete(Query query, Class<?> entity) {elasticsearchRestTemplate.delete(query, entity, elasticsearchRestTemplate.getIndexCoordinatesFor(entity));return true;}}
?delete(刪除通過query所搜索到的所有數據) 刪除文檔測試結果:
- 通過match詞條分詞 取并集查詢后 結果被刪除
- ik_smart: 粗粒度分詞 山東省濟南市 被分為(“山東省”,“濟南市”)
- 只要tAddress字段里包含 山東省和濟南市 就會被查詢到 然后被刪除
import com.it.mhh.elasticsearch.controller.ElasticsearchDeleteController; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermsQueryBuilder; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.test.context.junit4.SpringRunner;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchDeleteControllerTest {@Autowiredprivate ElasticsearchDeleteController elasticsearchDeleteController;/*** @param query : 刪除掉被query所搜索到的所有數據。* @param entity : 刪除的哪個索引的數據(從傳入對象中的@Document注解中indexName屬性獲取)* @return java.lang.Boolean* @explain :* @Author Mhh* @Date 2021/12/27 14:22*/@Testpublic void deleteByQuery() {//查詢條件(詞條查詢:對應ES query里的match)MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("tAddress", "山東省濟南市").operator(Operator.AND).analyzer("ik_smart");//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchQueryBuilder);Boolean aBoolean = elasticsearchDeleteController.delete(nativeSearchQuery, Teacher.class);System.err.println(aBoolean);} }
?7.elasticsearchRestTemplate 修改
-
7.1 update 修改文檔(根據主鍵修改)
-
- update(UpdateQuery query, IndexCoordinates index)
???????????query:要修改參數的主鍵及修改值
???????????index:指定索引 - bulkUpdate(
List<UpdateQuery>
queries, IndexCoordinates index):批量修改
update 修改文檔(根據主鍵修改)測試
- id: 表示要修改哪個文檔(_id)
- object:要修改的值對象(這里的對象最終都會轉成Map)注意 這里屬性值如果是空或null的話 那么也會被更新
?????????????用的 hutool-core轉map(版本高一些,低版本的 如果傳的就是Map類型,在map轉map時會報錯 – 5.7.13) - classType : 修改的哪個索引實體 (主要是獲取對象里面@Document注解indexName屬性獲取修改哪個索引里的數據
- update(UpdateQuery query, IndexCoordinates index)
-
7.1.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchUpdateService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 修改類*/ @RestController @RequestMapping("/elasticSearch/update") public class ElasticsearchUpdateController {@Autowiredprivate ElasticsearchUpdateService elasticsearchUpdateService;/*** @param id : 主鍵id(es里的_id)* @param object : 要修改的數據(這里的值都會轉成Map)注意 這里入參如果是空或null的話 那么也會被更新* // 用的 hutool-core轉map(版本高一些,低版本的 如果傳的就是Map類型,在map轉map時會報錯 -- 5.7.13)* @param classType : 修改的哪個索引實體 (主要是獲取對象里面@Document注解indexName屬性獲取修改哪個索引里的數據* @return java.lang.Boolean* @explain : 根據主鍵修改數據* @Author Mhh* @Date 2021/12/27 11:16*/@PostMapping("update")public Boolean update(@RequestParam("id") String id, @RequestBody Object object, Class<?> classType) {return elasticsearchUpdateService.update(id, object, classType);} }
?7.1.2 service層
/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 修改*/ public interface ElasticsearchUpdateService {/*** @param id : 主鍵id(es里的_id)* @param object : 要修改的數據(這里的值都會轉成Map)注意 這里入參屬性值如果是空或null的話 那么也會被更新* // 用的 hutool-core轉map(版本高一些,低版本的 如果傳的就是Map類型,在map轉map時會報錯 -- 5.7.13)* @param classType : 修改的哪個索引實體 (主要是獲取對象里面@Document注解indexName屬性獲取修改哪個索引里的數據* @return java.lang.Boolean* @explain : 根據主鍵修改數據* @Author Mhh* @Date 2021/12/27 11:16*/Boolean update(String id, Object object, Class<?> classType); }
?7.1.3 serviceimpl層
import cn.hutool.core.bean.BeanUtil; import com.it.mhh.elasticsearch.service.ElasticsearchUpdateService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; 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.Service;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 修改*/ @Service public class ElasticsearchUpdateServiceImp implements ElasticsearchUpdateService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param id : 主鍵id(es里的_id)* @param object : 要修改的數據(這里的值都會轉成Map)注意 這里入參如果是空或null的話 那么也會被更新* // 用的 hutool-core轉map(版本高一些,低版本的 如果傳的就是Map類型,在map轉map時會報錯 -- 5.7.13)* @param classType : 修改的哪個索引實體 (主要是獲取對象里面@Document注解indexName屬性獲取修改哪個索引里的數據* @return java.lang.Boolean* @explain : 根據主鍵修改數據* @Author Mhh* @Date 2021/12/27 11:16*/@Overridepublic Boolean update(String id, Object object, Class<?> classType) {UpdateQuery.Builder builder = UpdateQuery.builder(id).withDocument(org.springframework.data.elasticsearch.core.document.Document.from(BeanUtil.beanToMap(object)));IndexCoordinates of = IndexCoordinates.of(classType.getAnnotation(Document.class).indexName());UpdateResponse update = elasticsearchRestTemplate.update(builder.build(), of);return true;}}
?update 修改文檔(根據主鍵修改)測試結果:
- 據主鍵id修改(這里如果修改時沒找到主鍵id就會報錯)
- 這里可以復用es的插入(存入時es里已經有此主鍵就是修改,沒有就是新增)
- 注意屬性值是否為null值 es不會分辨 只會更新(即使是null值也會更新)
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.controller.ElasticsearchUpdateController; import com.it.mhh.elasticsearch.entity.Teacher; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.HashMap; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchUpdateControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;@Autowiredprivate ElasticsearchUpdateController elasticsearchUpdateController;/** 根據主鍵id修改(這里如果修改時沒找到主鍵id就會報錯)[這里可以復用es的插入(存入時es里已經有此主鍵就是修改,沒有就是刪除)]* */@Testpublic void updateByIdES() {Teacher teacher = elasticsearchSelectController.get("2", Teacher.class);//Teacher(tId=2, tName=小白老師, tEnglishName=white, tClassName=二班, tAddress=山東省濟南市歷下區, tFamous=此劍之勢,愈斬愈烈, tAge=17, tCreateTime=Wed Dec 29 14:20:50 CST 2021, completion=org.springframework.data.elasticsearch.core.completion.Completion@6cd2cb2)System.err.println(teacher);Map<String, Object> map = new HashMap<>();map.put("tName", "mhh");map.put("tAge", 11);map.put("tAddress",null);Boolean aBoolean = elasticsearchUpdateController.update("2", map, Teacher.class);//這里建議用map形式的(主要是它不能像sql智能,校驗null:如果傳了字段是null,那么就會修改成為null)System.err.println(aBoolean);//trueteacher = elasticsearchSelectController.get("2", Teacher.class);//Teacher(tId=2, tName=mhh, tEnglishName=white, tClassName=二班, tAddress=null, tFamous=此劍之勢,愈斬愈烈, tAge=11, tCreateTime=Wed Dec 29 14:20:50 CST 2021, completion=org.springframework.data.elasticsearch.core.completion.Completion@1d1cfe4)System.err.println(teacher);}}
?8.elasticsearchRestTemplate 查詢
-
8.1 get 查詢文檔(根據主鍵查詢)
-
- get(String id, Class<?> clazz)
?????id:文檔主鍵
?????clazz:類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])
get 查詢文檔(根據主鍵查詢)測試
- 根據主鍵id查詢數據
- get(String id, Class<?> clazz)
-
8.1.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param id : 主鍵id* @param classType : 類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])* @return T* @explain : 根據主鍵id查詢數據* @Author Mhh* @Date 2021/12/10 10:46*/@PostMapping("get")public <T> T get(String id, Class<T> classType) {return elasticsearchSelectService.get(id, classType);} }
?8.1.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param id : 主鍵id* @param classType : 類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])* @return T* @explain : 根據主鍵id查詢數據* @Author Mhh* @Date 2021/12/10 10:46*/public <T> T get(String id, Class<T> classType);}
?8.1.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param id : 主鍵id* @param classType : 類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])* @return T* @explain : 根據主鍵id查詢數據* @Author Mhh* @Date 2021/12/10 10:46*/@Overridepublic <T> T get(String id, Class<T> classType) {T t = elasticsearchRestTemplate.get(id, classType);return t;}}
?get 查詢文檔(根據主鍵查詢)測試結果:
- 根據主鍵id查詢結果
- 獲取不到就是null
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢@Testpublic void selectByIdES() {Teacher teacher = elasticsearchSelectController.get("2", Teacher.class);System.err.println(teacher);//Teacher(tId=2, tName=小白老師, tAge=17, tCreateTime=Sat Dec 04 10:43:34 CST 2021)Student student = elasticsearchSelectController.get("1", Student.class);System.err.println(student);/*Student(sId=1, sName=mhh, sAddress=濟南, sAge=12, sCreateTime=Sat Dec 04 10:34:14 CST 2021,sHeadmaster=Headmaster(hId=1, hName=小白主任, hAddress=山東, hSalary=7500, hClass=[一班, 二班], hCreateTime=Sat Dec 04 10:34:14 CST 2021),sCourseList=[語文, 數學, 英語],sColorList=[red, white, black],sTeacherList=[Teacher(tId=2, tName=小黑, tAge=13, tCreateTime=Sat Dec 04 10:34:14 CST 2021), Teacher(tId=2, tName=小藍, tAge=14, tCreateTime=Sat Dec 04 10:34:14 CST 2021)])*/Student nullStudent = elasticsearchSelectController.get("11", Student.class);//測試沒有此主鍵的查詢System.err.println(nullStudent); // null}}
-
8.2 exists 查詢文檔(判斷主鍵id是否存在)
-
- exists(String id, Class<?> clazz)
????????id:文檔主鍵
????????clazz:類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引]) - exists(String id, IndexCoordinates index)
????????id:文檔主鍵
????????index:指定索引
exists 查詢文檔(判斷主鍵id是否存在)測試
- 根據主鍵id查詢索引中是否存在此文檔
- exists(String id, Class<?> clazz)
-
8.2.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param id : 主鍵id* @param classType : 類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])* @return java.lang.Boolean* @explain : 判斷主鍵id是否存在* @Author Mhh* @Date 2021/12/29 14:54*/@PostMapping("exists")public Boolean exists(String id, Class<?> classType) {return elasticsearchSelectService.exists(id, classType);}}
?8.2.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param id : 主鍵id* @param classType : 類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])* @return java.lang.Boolean* @explain : 判斷主鍵id是否存在* @Author Mhh* @Date 2021/12/29 14:54*/public Boolean exists(String id, Class<?> classType);}
?8.2.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param id : 主鍵id* @param classType : 類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])* @return java.lang.Boolean* @explain : 判斷主鍵id是否存在* @Author Mhh* @Date 2021/12/29 14:54*/@Overridepublic Boolean exists(String id, Class<?> classType) {return elasticsearchRestTemplate.exists(id, classType);}}
?exists 查詢文檔(判斷主鍵id是否存在)測試結果:
- 根據主鍵id判斷此索引中是否有此文檔(有返回true,沒有返回false)
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param id : 主鍵id* @param classType : 類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])* @return java.lang.Boolean* @explain : 判斷主鍵id是否存在* @Author Mhh* @Date 2021/12/29 14:54*/@Testpublic void exists() {Boolean exists = elasticsearchSelectController.exists("11", Teacher.class);System.err.println(exists);//false}}
- 根據主鍵id判斷此索引中是否有此文檔(有返回true,沒有返回false)
-
8.3 queryForPage 查詢文檔(分頁查詢)
-
- queryForPage(Query query, Class<?> clazz, IndexCoordinates index)
????????query:查詢語法 包含(term查詢、terms查詢、match查詢、范圍查詢、模糊查詢…)
????????clazz:類對象(用來獲取這個對象中的@Document注解中indexName屬性[表示查詢那個索引])
????????index:指定索引
queryForPage 查詢文檔(分頁查詢)測試
- NativeSearchQueryBuilder withPageable(Pageable pageable)
- 構建Pageable 對象 進行分頁
- 添加分頁信息 不設置 默認10條(用查詢條件構建器)
- queryForPage(Query query, Class<?> clazz, IndexCoordinates index)
-
8.3.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param pageNum : 分頁查詢的頁數* @param pageSize : 分頁查詢返回的每頁個數* @param key : 查詢es的字段名* @param value : 要查詢字段名中的值* @param classType : 返回的類類型* @return List<T></T>* @throws* @Author Mhh* @Date 2021/12/9 10:36*/@PostMapping("selectFindPage")public <T> List<T> selectFindPage(Integer pageNum, Integer pageSize, String key, String value, Class<T> classType) {return elasticsearchSelectService.selectFindPage(pageNum, pageSize, key, value, classType);}}
?8.3.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param pageNum : 分頁查詢的頁數* @param pageSize : 分頁查詢返回的每頁個數* @param key : 查詢es的字段名* @param value : 要查詢字段名中的值* @param classType : 返回的類類型* @return List<T></T>* @throws* @Author Mhh* @Date 2021/12/9 10:36*/public <T> List<T> selectFindPage(Integer pageNum, Integer pageSize, String key, String value, Class<T> classType);}
?8.3.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param pageNum : 分頁查詢的頁數* @param pageSize : 分頁查詢返回的每頁個數* @param key : 查詢es的字段名* @param value : 要查詢字段名中的值* @param classType : 返回的類類型* @return List<T></T>* @throws* @Author Mhh* @Date 2021/12/9 10:36*/public <T> List<T> selectFindPage(Integer pageNum, Integer pageSize, String key, String value, Class<T> classType) {NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(key, value).analyzer("ik_smart");//分詞查詢(這里指定分詞只是分傳過來的參數)[它是要和es索引里的分詞后數據一一對應才能返回]/*例子:前臺傳了 (山東省:粗粒度分為山東省 細粒度分為:山東省,山東,省)es索引庫里(山東省濟南市 粗粒度分為 山東省,濟南市 細粒度分為:山東省,山東,省,濟南市,濟南,市)只有當前臺分的詞和后臺分的詞能有一個匹配上就可以*/nativeSearchQueryBuilder.withQuery(matchQueryBuilder);nativeSearchQueryBuilder.withPageable(PageRequest.of(pageNum == null || pageNum == 0 ? 0 : pageNum - 1, pageSize));//4.構建查詢對象NativeSearchQuery query = nativeSearchQueryBuilder.build();IndexCoordinates of = IndexCoordinates.of(classType.getAnnotation(Document.class).indexName());AggregatedPage<T> page = elasticsearchRestTemplate.queryForPage(query, classType, of);long totalElements = page.getTotalElements(); // 總記錄數int totalPages = page.getTotalPages(); // 總頁數int pageNumber = page.getPageable().getPageNumber(); // 當前頁號List<T> beanList = page.toList(); // 當前頁數據集Set<T> beanSet = page.toSet(); // 當前頁數據集return page.getContent();}}
?queryForPage 查詢文檔(分頁查詢)測試結果:
- match分詞查詢 默認并集 ES索引中可看出符合的有兩條,最終通過分頁返回一條
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param pageNum : 分頁查詢的頁數* @param pageSize : 分頁查詢返回的每頁個數* @param key : 查詢es的字段名* @param value : 要查詢字段名中的值* @param classType : 返回的類類型* @return List<T></T>* @throws* @Author Mhh* @Date 2021/12/9 10:36*/@Testpublic void selectFindPage() {List<Teacher> teacherList = elasticsearchSelectController.selectFindPage(1, 1, "tAddress", "山東省", Teacher.class);System.out.println(teacherList.size());// 1}}
- match分詞查詢 默認并集 ES索引中可看出符合的有兩條,最終通過分頁返回一條
-
8.4 AnalyzeRequest (根據入參內容返回分詞后結果)
-
- tokenizer: 選擇粗細粒度分詞器
- text: 需要分詞的內容
AnalyzeRequest (根據入參內容返回分詞后結果)測試
- 粗粒度分詞器:ik_smart
???????????粗粒度分詞—北京天安門:[北京,天安門] - 細粒度分詞器:ik_max_word
???????????細粒度分詞—北京天安門:[北京,天安門,天安,門]
-
8.4.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param tokenizer : 粗細粒度分詞(粗粒度:ik_smart 細粒度:ik_max_word)* @param text : 需要分詞的入參* @return java.util.List<org.elasticsearch.client.indices.AnalyzeResponse.AnalyzeToken>* @throws* @explain* @Author Mhh* @Date 2021/12/9 16:16*/@PostMapping("selectBreakUpText")public List<AnalyzeResponse.AnalyzeToken> selectBreakUpText(String tokenizer, String text) throws NoSuchFieldException, IllegalAccessException, IOException {return elasticsearchSelectService.selectBreakUpText(tokenizer, text);}}
?8.4.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param tokenizer : 粗細粒度分詞(粗粒度:ik_smart 細粒度:ik_max_word)* @param text : 需要分詞的入參* @return java.util.List<org.elasticsearch.client.indices.AnalyzeResponse.AnalyzeToken>* @throws* @explain* @Author Mhh* @Date 2021/12/9 16:16*/public List<AnalyzeResponse.AnalyzeToken> selectBreakUpText(String tokenizer, String text) throws NoSuchFieldException, IllegalAccessException, IOException;}
?8.4.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param tokenizer : 粗細粒度分詞(粗粒度:ik_smart 細粒度:ik_max_word)* @param text : 需要分詞的入參* @return java.util.List<org.elasticsearch.client.indices.AnalyzeResponse.AnalyzeToken>* @throws* @explain* @Author Mhh* @Date 2021/12/9 16:16*/public List<AnalyzeResponse.AnalyzeToken> selectBreakUpText(String tokenizer, String text) throws IOException {RestHighLevelClient restHighLevelClient = elasticsearchRestTemplate.execute((client) -> client);AnalyzeRequest request = AnalyzeRequest.buildCustomAnalyzer(tokenizer).build(text);AnalyzeResponse response = restHighLevelClient.indices().analyze(request, RequestOptions.DEFAULT);return response.getTokens(); //-------------------------------這兩種都可以--------------------------------------------------------------------- // AnalyzeRequest request = AnalyzeRequest.buildCustomAnalyzer(tokenizer).build(text); // Class<? extends ElasticsearchRestTemplate> aClass = elasticsearchRestTemplate.getClass();//反射 // Field client = aClass.getDeclaredField("client");//獲得 ElasticsearchRestTemplate里的client屬性 // client.setAccessible(true);//私有權限解除 // RestHighLevelClient restHighLevelClient = (RestHighLevelClient) client.get(elasticsearchRestTemplate); // AnalyzeResponse response = restHighLevelClient.indices().analyze(request, RequestOptions.DEFAULT); // return response.getTokens();}}
?AnalyzeRequest (根據入參內容返回分詞后結果)測試結果:
- 通過查詢分詞后結果來校驗 分詞后查詢文檔返回的解果是否正確
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param tokenizer : 粗細粒度分詞(粗粒度:ik_smart 細粒度:ik_max_word)* @param text : 需要分詞的入參* @return java.util.List<org.elasticsearch.client.indices.AnalyzeResponse.AnalyzeToken>* @throws* @explain* @Author Mhh* @Date 2021/12/9 16:16*/@Testpublic void breakUpText() throws IllegalAccessException, NoSuchFieldException, IOException {List<AnalyzeResponse.AnalyzeToken> maxAnalyzeTokens = elasticsearchSelectController.selectBreakUpText("ik_max_word", "北京天安門");//細粒度分詞List<AnalyzeResponse.AnalyzeToken> smartAnalyzeTokens = elasticsearchSelectController.selectBreakUpText("ik_smart", "北京天安門");//粗粒度分詞System.err.println("maxAnalyzeTokens細粒度的size:" + maxAnalyzeTokens.size() + "\n" + "smartAnalyzeTokens粗粒度的size:" + smartAnalyzeTokens.size());}}
- 通過查詢分詞后結果來校驗 分詞后查詢文檔返回的解果是否正確
-
8.5 termQuery 查詢文檔(入參不分詞,精確匹配)
-
- termsQuery(String name, Object… values)
- termsQuery(String name, String… values)
- termsQuery(String name, long… values)
- termsQuery(String name, int… values)
- …
????????name: 域(字段名)
????????values:一域多值, 查詢的值
termQuery 查詢文檔(入參不分詞,精確匹配)測試
- 入參不分詞 會查詢ES索引中文檔(如果ES中索引文檔被分詞.只要匹配到詞條就可以返回)
- values:一域多值(只要匹配到一個值就可以返回)
-
8.5.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain :詞條查詢:不分詞,精確匹配* @Author Mhh* @Date 2021/12/10 14:28*/@PostMapping("termQuery")public <T> List<T> termQuery(String key, Class<T> classType, String... values) {return elasticsearchSelectService.termQuery(key, classType, values);}}
?8.5.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain :詞條查詢(不分前端傳過來的數據)* @Author Mhh* @Date 2021/12/10 14:28*/public <T> List<T> termQuery(String key, Class<T> classType, String... values);}
?8.5.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain :詞條查詢(不分前端傳過來的數據)* @Author Mhh* @Date 2021/12/10 14:28*/public <T> List<T> termQuery(String key, Class<T> classType, String... values) {//查詢條件(詞條查詢:對應ES query里的term)TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(key, values);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(termsQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?termQuery 查詢文檔(入參不分詞,精確匹配)測試結果:
- term查詢,查詢text類型字段時,只有其中的單詞相匹配都會查到,text字段會對數據進行分詞
- term查詢,查詢keyword類型字段時,只有完全匹配才會查到,keyword字段不會對數據進行分詞
- term query會去倒排索引中尋找確切的term,它并不知道分詞器的存在。這種查詢適合keyword?、numeric、date
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain :詞條查詢:不分詞,精確匹配* @Author Mhh* @Date 2021/12/10 14:28*/@Testpublic void termQuery() {List<Teacher> teacherList = elasticsearchSelectController.termQuery("tAddress", Teacher.class, "泰安市", "河北省");teacherList.forEach(System.err::println);}}
-
8.6 match 查詢文檔(會對查詢條件進行分詞)
-
- matchQuery(String name, Object text)
????????name: 域(字段名)
????????text: 要查詢的入參值
match查詢文檔(會對查詢條件進行分詞)測試
- 會對查詢條件進行分詞。
- 將分詞后的查詢條件和詞條進行等值匹配
- 默認取并集(OR)
- matchQuery(String name, Object text)
-
8.6.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** 入參分詞: 山東省濟南市 ik_smart粗粒度:[山東省,濟南市] ik_max_word細粒度:[山東省,山東,省,濟南市,濟南,南市]** @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param text : 查詢的值* @return java.util.List<T>* @explain :matchQuery:詞條分詞查詢(會對查詢條件進行分詞)* @Author Mhh* @Date 2021/12/10 15:21*/@PostMapping("matchQuery")public <T> List<T> matchQuery(Operator operator, String analyzer, String key, Class<T> classType, String text) {return elasticsearchSelectService.matchQuery(operator, analyzer, key, classType, text);}}
?8.6.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** 入參分詞: 山東省濟南市 ik_smart粗粒度:[山東省,濟南市] ik_max_word細粒度:[山東省,山東,省,濟南市,濟南,南市]** @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param text : 查詢的值* @return java.util.List<T>* @explain :matchQuery:詞條分詞查詢(會對查詢條件進行分詞)* @Author Mhh* @Date 2021/12/10 15:21*/public <T> List<T> matchQuery(Operator operator, String analyzer, String key, Class<T> classType, String text);}
?8.6.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** 入參分詞: 山東省濟南市 ik_smart粗粒度:[山東省,濟南市] ik_max_word細粒度:[山東省,山東,省,濟南市,濟南,南市]** @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param text : 查詢的值* @return java.util.List<T>* @explain :matchQuery:詞條分詞查詢(會對查詢條件進行分詞)* @Author Mhh* @Date 2021/12/10 15:21*/public <T> List<T> matchQuery(Operator operator, String analyzer, String key, Class<T> classType, String text) {//查詢條件(詞條查詢:對應ES query里的match)MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(key, text).analyzer(analyzer).operator(operator);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?match 查詢文檔(會對查詢條件進行分詞)測試結果:
- match query知道分詞器的存在。并且理解是如何被分詞的
- Operator:
???????????Operator.AND:交集
(表示被分詞后的值都包含
在域(字段)中就返回此數據)
???????????Operator.OR:??并集
(表示被分詞后的值只要有一個
被包含在域(字段)中就返回此數據)
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** 入參分詞: 山東省濟南市 ik_smart粗粒度:[山東省,濟南市] ik_max_word細粒度:[山東省,山東,省,濟南市,濟南,南市]** @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param key : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param text : 查詢的值* @return java.util.List<T>* @explain :matchQuery:詞條分詞查詢(會對查詢條件進行分詞)* @Author Mhh* @Date 2021/12/10 15:21*/@Testpublic void matchQuery() {List<Teacher> teacherList =elasticsearchSelectController.matchQuery(Operator.AND,"ik_smart","tAddress",Teacher.class,"山東省濟南市");teacherList.forEach(System.err::println);}}
-
8.7 matchAllQuery 查詢文檔(查詢此索引下所有文檔)
-
- matchAllQuery():匹配所有文檔的查詢。
matchAllQuery 查詢文檔(查詢此索引下所有文檔)測試
- 查詢指定索引下所有文檔 (默認十條)
-
8.7.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 返回索引庫里所有數據* @Author Mhh* @Date 2021/12/10 15:44*/@PostMapping("matchAllQuery")public <T> List<T> matchAllQuery(Class<T> classType) {return elasticsearchSelectService.matchAllQuery(classType);}}
?8.7.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 返回索引庫里所有數據* @Author Mhh* @Date 2021/12/10 15:44*/public <T> List<T> matchAllQuery(Class<T> classType);}
?8.7.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 返回索引庫里所有數據* @Author Mhh* @Date 2021/12/10 15:44*/public <T> List<T> matchAllQuery(Class<T> classType) {//查詢條件(詞條查詢:對應ES query里的match)MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchAllQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?matchAllQuery 查詢文檔(查詢此索引下所有文檔)測試結果:
- 通過入參對象里面@Document注解indexName屬性獲取查詢哪個索引
- 返回指定索引下所有文檔
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 返回索引庫里所有數據* @Author Mhh* @Date 2021/12/10 15:44*/@Testpublic void matchAllQuery() {List<Teacher> teacherList = elasticsearchSelectController.matchAllQuery(Teacher.class);teacherList.forEach(System.err::println);} }
-
8.8 wildcardQuery 查詢文檔(模糊查詢)
-
- wildcardQuery(String name, String query)
??????????????????????name:?域名(字段名稱)
??????????????????????query: 通配符查詢字符串
wildcardQuery 查詢文檔(模糊查詢)測試
- wildcard查詢:會對查詢條件進行分詞,還可以使用通配符
?
?: 任意單個字符*
?: 0個或多個字符
- wildcardQuery(String name, String query)
-
8.8.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/** ?:只包含一個字符* 山?省: 山東省 或者 山西省 等等 ?包含一個字符* ??省: 山東省 或者 吉林省 等等 ?包含一個字符* ???: 你好啊 或者 早上好 等等 ?包含一個字符** *:表示0個或多個字符* 濟南*: 濟南市 或者 濟南市歷下區..... *表示0個或多個字符* *劍 : 長虹劍 或者 冰魄長虹倚天劍.... *表示0個或多個字符** 注意: *或者?放在最前面(例如:*省 | ?省 *為 | ?為) 會引發全表(全索引)掃描 注意效率問題* *//*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : wildcardQuery模糊查詢(會對查詢條件分詞,還可以使用通配符)[?:表示任意單個字符][*:表示0或多個字符]* @Author Mhh* @Date 2021/12/10 16:10*/@PostMapping("wildcardQuery")public <T> List<T> wildcardQuery(String key, String value, Class<T> classType) {return elasticsearchSelectService.wildcardQuery(key, value, classType);}}
?8.8.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/** ?:只包含一個字符* 山?省: 山東省 或者 山西省 等等 ?包含一個字符* ??省: 山東省 或者 吉林省 等等 ?包含一個字符* ???: 你好啊 或者 早上好 等等 ?包含一個字符** *:表示0個或多個字符* 濟南*: 濟南市 或者 濟南市歷下區..... *表示0個或多個字符* *劍 : 長虹劍 或者 冰魄長虹倚天劍.... *表示0個或多個字符** 注意: *或者?放在最前面(例如:*省 | ?省 *為 | ?為) 會引發全表(全索引)掃描 注意效率問題* *//*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : wildcardQuery模糊查詢(會對查詢條件分詞,還可以使用通配符)[?:表示任意單個字符][*:表示0或多個字符]* @Author Mhh* @Date 2021/12/10 16:10*/public <T> List<T> wildcardQuery(String key, String value, Class<T> classType);}
?8.8.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/** ?:只包含一個字符* 山?省: 山東省 或者 山西省 等等 ?包含一個字符* ??省: 山東省 或者 吉林省 等等 ?包含一個字符* ???: 你好啊 或者 早上好 等等 ?包含一個字符** *:表示0個或多個字符* 濟南*: 濟南市 或者 濟南市歷下區..... *表示0個或多個字符* *劍 : 長虹劍 或者 冰魄長虹倚天劍.... *表示0個或多個字符** 注意: *或者?放在最前面(例如:*省 | ?省 *為 | ?為) 會引發全表(全索引)掃描 注意效率問題* *//*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : wildcardQuery模糊查詢(會對查詢條件分詞,還可以使用通配符)[?:表示任意單個字符][*:表示0或多個字符]* @Author Mhh* @Date 2021/12/10 16:10*/public <T> List<T> wildcardQuery(String key, String value, Class<T> classType) {//查詢條件(詞條查詢:對應ES query里的wildcard)WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(key, value);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(wildcardQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?wildcardQuery 查詢文檔(模糊查詢)測試結果:
"*華*"
?包含華字的"華*"
?華字后邊零個或多個字符"華?"
?華字后邊一個字符"*華"
或"?華"
?會引發全表(全索引)掃描 注意效率問題
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : wildcardQuery模糊查詢(會對查詢條件分詞,還可以使用通配符)[?:表示任意單個字符][*:表示0或多個字符]* @Author Mhh* @Date 2021/12/10 16:10*/@Testpublic void wildcardQuery() {List<Teacher> teacherList = elasticsearchSelectController.wildcardQuery("tAddress","山?省",Teacher.class);teacherList.forEach(System.err::println);} }
-
8.9 prefixQuery 查詢文檔(前綴查詢)
-
- prefixQuery(String name, String prefix)
??????????????????????name:?域名(字段名稱)
??????????????????????prefix: 前綴值查詢
prefixQuery 查詢文檔(前綴查詢)測試
- 前綴查詢 對keyword類型支持比較好
- prefixQuery(String name, String prefix)
-
8.9.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : prefixQuery 前綴查詢 對keyword類型支持比較好(text也能用:索引庫字段分詞后 分的詞前綴要是能匹配也是可以返回此數據)* @Author Mhh* @Date 2021/12/10 16:49*/@PostMapping("prefixQuery")public <T> List<T> prefixQuery(String key, String value, Class<T> classType) {return elasticsearchSelectService.prefixQuery(key, value, classType);}}
?8.9.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : prefixQuery 前綴查詢 對keyword類型支持比較好(text也能用:索引庫字段分詞后 分的詞前綴要是能匹配也是可以返回此數據)* @Author Mhh* @Date 2021/12/10 16:49*/public <T> List<T> prefixQuery(String key, String value, Class<T> classType); }
?8.9.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : prefixQuery 前綴查詢 對keyword類型支持比較好(text也能用:索引庫字段分詞后 分的詞前綴要是能匹配也是可以返回此數據)* @Author Mhh* @Date 2021/12/10 16:49*/public <T> List<T> prefixQuery(String key, String value, Class<T> classType) {//查詢條件(詞條查詢:對應ES query里的prefixQuery)PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery(key, value);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(prefixQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?prefixQuery 查詢文檔(前綴查詢)測試結果:
- text也能用:索引庫字段分詞后 分的詞前綴要是能匹配也是可以返回此數據
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : prefixQuery 前綴查詢 對keyword類型支持比較好(text也能用:索引庫字段分詞后 分的詞前綴要是能匹配也是可以返回此數據)* @Author Mhh* @Date 2021/12/10 16:49*/@Testpublic void prefixQuery() {List<Teacher> teacherList =elasticsearchSelectController.prefixQuery("tAddress","濟",Teacher.class);teacherList.forEach(System.err::println);} }
- text也能用:索引庫字段分詞后 分的詞前綴要是能匹配也是可以返回此數據
-
8.10 regexpQuery 查詢文檔(正則表達式查詢)
-
- regexpQuery(String name, String regexp)
??????????????????????name:?域名(字段名稱)
??????????????????????regexp: 正則表達式
regexpQuery 查詢文檔(正則表達式查詢)測試
- 匹配包含具有指定正則表達式的術語的文檔的查詢
- 菜鳥教程-正則表達式:?正則表達式 – 語法 | 菜鳥教程.
- regexpQuery(String name, String regexp)
-
8.10.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 正則表達式查詢:regexpQuery* @Author Mhh* @Date 2021/12/11 19:17*/@PostMapping("regexpQuery")public <T> List<T> regexpQuery(String key, String value, Class<T> classType) {return elasticsearchSelectService.regexpQuery(key, value, classType);}}
?8.10.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 正則表達式查詢:regexpQuery* @Author Mhh* @Date 2021/12/11 19:17*/public <T> List<T> regexpQuery(String key, String value, Class<T> classType);}
?8.10.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 正則表達式查詢:regexpQuery* @Author Mhh* @Date 2021/12/11 19:17*/public <T> List<T> regexpQuery(String key, String value, Class<T> classType) {//查詢條件(詞條查詢:對應ES query里的regexpQuery)RegexpQueryBuilder regexpQueryBuilder = QueryBuilders.regexpQuery(key, value);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(regexpQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());} }
?regexpQuery 查詢文檔(正則表達式查詢) 測試結果:
- 正則查詢取決于正則表達式的效率
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param key : es里索引的域(字段名)* @param value : 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 正則表達式查詢:regexpQuery* @Author Mhh* @Date 2021/12/11 19:17*/@Testpublic void regexpQuery() {List<Teacher> teacherEnglishNameList = elasticsearchSelectController.regexpQuery("tEnglishName","b+(.)*",Teacher.class);teacherEnglishNameList.forEach(System.err::println);System.out.println("---------------------------------------");List<Teacher> teacherNameList =elasticsearchSelectController.regexpQuery("tName","小白+(.)*",Teacher.class);teacherNameList.forEach(System.err::println);}}
- 正則查詢取決于正則表達式的效率
-
8.11 rangeQuery 查詢文檔(范圍查詢)
-
- rangeQuery(String name).from(Object from,boolean includeLower).to(Object to,boolean includeLower)
????????????????????name:?域名(字段名稱)
????????????????????from: 范圍查詢的from部分, Null 表示無界
????????????????????includeLower:是否包含 默認為true[包含]
????????????????????to: 范圍查詢的to部分, Null 表示無界
????????????????????includeLower:是否包含 默認為true[包含]
rangeQuery 查詢文檔(范圍查詢) 測試
- 支持范圍查詢的字段類型有:數值、日期、地址的IP范圍。
- rangeQuery(String name).from(Object from,boolean includeLower).to(Object to,boolean includeLower)
-
8.11.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param name :es里索引的域(字段名)* @param from :范圍查詢值 1 from(Object from, boolean includeLower) includeLower:是否包含 默認為true[包含]* // 如果from==null 那么就是<=to的* @param to :范圍查詢值 2 to(Object to, boolean includeUpper) includeLower:是否包含 默認為true[包含]* // 如果to==null 那么就是 >=from的* @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : rangeQuery 范圍查詢* @Author Mhh* @Date 2021/12/12 18:13*/@PostMapping("rangeQuery")public <T> List<T> rangeQuery(String name, Integer from, Integer to, Class<T> classType) {return elasticsearchSelectService.rangeQuery(name, from, to, classType);} }
?8.11.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param name :es里索引的域(字段名)* @param from :范圍查詢值 1 from(Object from, boolean includeLower) includeLower:是否包含 默認為true[包含]* // 如果from==null 那么就是<=to的* @param to :范圍查詢值 2 to(Object to, boolean includeUpper) includeLower:是否包含 默認為true[包含]* // 如果to==null 那么就是 >=from的* @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : rangeQuery 范圍查詢* @Author Mhh* @Date 2021/12/12 18:13*/public <T> List<T> rangeQuery(String name, Integer from, Integer to, Class<T> classType);}
?8.11.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param name :es里索引的域(字段名)* @param from :范圍查詢值 1 from(Object from, boolean includeLower) includeLower:是否包含 默認為true[包含]* // 如果from==null 那么就是<=to的* @param to :范圍查詢值 2 to(Object to, boolean includeUpper) includeLower:是否包含 默認為true[包含]* // 如果to==null 那么就是 >=from的* @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : rangeQuery 范圍查詢* @Author Mhh* @Date 2021/12/12 18:13*/public <T> List<T> rangeQuery(String name, Integer from, Integer to, Class<T> classType) {//查詢條件(詞條查詢:對應ES query里的rangeQuery)RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(name).from(from).to(to);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(rangeQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?rangeQuery 查詢文檔(范圍查詢) 測試結果:
includeLower=true;(是否包含 默認為true[包含])
- 如果from==null 那么就是<=to的
- 如果to==null 那么就是 >=from的
- 如果 from!=null && to!=null 那么就是from>=to的
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param name :es里索引的域(字段名)* @param from :范圍查詢值 1 from(Object from, boolean includeLower) includeLower:是否包含 默認為true[包含]* // 如果from==null 那么就是<=to的* @param to :范圍查詢值 2 to(Object to, boolean includeUpper) includeLower:是否包含 默認為true[包含]* // 如果to==null 那么就是 >=from的* @param classType :返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : rangeQuery 范圍查詢* @Author Mhh* @Date 2021/12/12 18:13*/@Testpublic void rangeQuery() {List<Teacher> lteTeacherList = elasticsearchSelectController.rangeQuery("tAge", null, 18, Teacher.class);lteTeacherList.forEach(System.err::println);System.out.println("-------------------------------------");List<Teacher> gteTeacherList = elasticsearchSelectController.rangeQuery("tAge", 18, null, Teacher.class);gteTeacherList.forEach(System.err::println);}}
-
8.12 Sort 查詢文檔 (排序)
-
- addSort(Sort sort): 添加排序
???????????by(Sort.Direction direction, String… properties)
????????????????????direction : 排序 Sort.Direction.ASC:升序 || Sort.Direction.DESC:降序
????????????????????properties :?域名(可變參數,可傳1至多個)
Sort 查詢文檔 (排序) 測試
- 在排序的過程中,只能使用可排序的屬性進行排序(數字、日期)
- addSort(Sort sort): 添加排序
-
8.12.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param direction : 排序 Sort.Direction.ASC:升序 || Sort.Direction.DESC:降序* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param properties : 域名(可變參數,可傳1至多個)* @return java.util.List<T>* @explain : 給查詢 結果排序* @Author Mhh* @Date 2021/12/12 18:45*/@PostMapping("sort")public <T> List<T> sort(Sort.Direction direction, Class<T> classType, String... properties) {return elasticsearchSelectService.sort(direction, classType, properties);} }
?8.12.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param direction : 排序 Sort.Direction.ASC:升序 || Sort.Direction.DESC:降序* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param properties : 域名(可變參數,可傳1至多個)* @return java.util.List<T>* @explain : 給查詢 結果排序* @Author Mhh* @Date 2021/12/12 18:45*/public <T> List<T> sort(Sort.Direction direction, Class<T> classType, String... properties);}
?8.12.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param direction : 排序 Sort.Direction.ASC:升序 || Sort.Direction.DESC:降序* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param properties : 域名(可變參數,可傳1至多個)* @return java.util.List<T>* @explain : 給查詢 結果排序* @Author Mhh* @Date 2021/12/12 18:45*/public <T> List<T> sort(Sort.Direction direction, Class<T> classType, String... properties) {//查詢條件(詞條查詢:對應ES query里的sort)MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchAllQueryBuilder);nativeSearchQuery.addSort(Sort.by(direction, properties));//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?Sort 查詢文檔 (排序) 測試結果:
- ES支持多級排序—sort : 將查詢結果首先按第一個自定義條件排序,當第一個 sort 值完全相同時,再按照第二個條件進行排序,以此類推。
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param direction : 排序 Sort.Direction.ASC:升序 || Sort.Direction.DESC:降序* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param properties : 域名(可變參數,可傳1至多個)* @return java.util.List<T>* @explain : 給查詢 結果排序* @Author Mhh* @Date 2021/12/12 18:45*/@Testpublic void sort() {List<Teacher> ascTeacherList = elasticsearchSelectController.sort(Sort.Direction.ASC, Teacher.class, "tAge");ascTeacherList.forEach(System.err::println);System.out.println("------------------------------------");List<Teacher> descTeacherList = elasticsearchSelectController.sort(Sort.Direction.DESC, Teacher.class, "tAge");descTeacherList.forEach(System.err::println);}}
- ES支持多級排序—sort : 將查詢結果首先按第一個自定義條件排序,當第一個 sort 值完全相同時,再按照第二個條件進行排序,以此類推。
-
8.13 queryStringQuery 查詢文檔 (多條件查詢 一值多域)
-
- queryStringQuery(String queryString).fields(Map<String, Float> fields).analyzer(String analyzer).defaultOperator(Operator defaultOperator)
?????????????????????????????queryString : 要運行的查詢字符串
?????????????????????????????fields : 添加多個域(字段)以及針對特定權重進行查詢。
?????????????????????????????analyzer : 選擇分詞器(對查詢的只進行分詞)
?????????????????????????????defaultOperator : Operator.OR 并集 || Operator.AND 交集
queryStringQuery 查詢文檔 (多條件查詢 一值多域) 測試
- queryString 多條件查詢
- 會對查詢條件進行分詞。
- 將分詞后的查詢條件和詞條進行等值匹配
- 默認取并集(OR)
- 可以指定多個查詢字段
- query_string:識別query中的連接符(or 、and)
- queryStringQuery(String queryString).fields(Map<String, Float> fields).analyzer(String analyzer).defaultOperator(Operator defaultOperator)
-
8.13.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/** 多域查詢的交并集理解:* OR: 只要有一個域中包含入參value被分詞后的"一個值"時就返回* AND: 只要有一個域中包含入參value被分詞后的"所有值"時返回** @param fields : Map<String,Float>類型:key為域名,Float為boost值* boost: 參數被用來提升一個語句的相對權重( boost 值大于 1 )或降低相對權重( boost 值處于 0 到 1 之間),但是這種提升或降低并不是線性的,換句話說,如果一個 boost 值為 2 ,并不能獲得兩倍的評分 _score 。* @param queryString : 要查詢的值 (會對查詢條件進行分詞)* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : queryString 多條件查詢* ?會對查詢條件進行分詞。* ?然后將分詞后的查詢條件和詞條進行等值匹配* ?默認取并集(OR)* ?可以指定多個查詢字段* ?query_string:識別query中的連接符(or 、and)* @Author Mhh* @Date 2021/12/12 19:45*/@PostMapping("queryStringQuery")public <T> List<T> queryStringQuery(Map<String, Float> fields, String queryString, String analyzer, Operator operator, Class<T> classType) {return elasticsearchSelectService.queryStringQuery(fields, queryString, analyzer, operator, classType);} }
?8.13.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/** 多域查詢的交并集理解:* OR: 只要有一個域中包含入參value被分詞后的"一個值"時就返回* AND: 只要有一個域中包含入參value被分詞后的"所有值"時返回** @param fields : Map<String,Float>類型:key為域名,Float為boost值* boost: 參數被用來提升一個語句的相對權重( boost 值大于 1 )或降低相對權重( boost 值處于 0 到 1 之間),但是這種提升或降低并不是線性的,換句話說,如果一個 boost 值為 2 ,并不能獲得兩倍的評分 _score 。* @param queryString : 要查詢的值 (會對查詢條件進行分詞)* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : queryString 多條件查詢* ?會對查詢條件進行分詞。* ?然后將分詞后的查詢條件和詞條進行等值匹配* ?默認取并集(OR)* ?可以指定多個查詢字段* ?query_string:識別query中的連接符(or 、and)* @Author Mhh* @Date 2021/12/12 19:45*/public <T> List<T> queryStringQuery(Map<String, Float> fields, String queryString, String analyzer, Operator operator, Class<T> classType);}
?8.13.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/** 多域查詢的交并集理解:* OR: 只要有一個域中包含入參value被分詞后的"一個值"時就返回* AND: 只要有一個域中包含入參value被分詞后的"所有值"時返回** @param fields : Map<String,Float>類型:key為域名,Float為boost值* boost: 參數被用來提升一個語句的相對權重( boost 值大于 1 )或降低相對權重( boost 值處于 0 到 1 之間),但是這種提升或降低并不是線性的,換句話說,如果一個 boost 值為 2 ,并不能獲得兩倍的評分 _score 。* @param queryString : 要查詢的值 (會對查詢條件進行分詞)* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : queryString 多條件查詢* ?會對查詢條件進行分詞。* ?然后將分詞后的查詢條件和詞條進行等值匹配* ?默認取并集(OR)* ?可以指定多個查詢字段* ?query_string:識別query中的連接符(or 、and)* @Author Mhh* @Date 2021/12/12 19:45*/public <T> List<T> queryStringQuery(Map<String, Float> fields, String queryString, String analyzer, Operator operator, Class<T> classType) {//查詢條件(詞條查詢:對應ES query里的queryStringQuery)QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(queryString).fields(fields).analyzer(analyzer).defaultOperator(operator);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(queryStringQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?queryStringQuery 查詢文檔 (多條件查詢 一值多域) 測試結果:
- query中的or and 是查詢時 匹配條件是否同時出現----or 出現一個即可,and 兩個條件同時出現
- default_operator的or and 是對結果進行 并集(or)、交集(and)
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/** 多域查詢的交并集理解:* OR: 只要有一個域中包含入參value被分詞后的"一個值"時就返回* AND: 只要有一個域中包含入參value被分詞后的"所有值"時返回** @param fields : Map<String,Float>類型:key為域名,Float為boost值* boost: 參數被用來提升一個語句的相對權重( boost 值大于 1 )或降低相對權重( boost 值處于 0 到 1 之間),但是這種提升或降低并不是線性的,換句話說,如果一個 boost 值為 2 ,并不能獲得兩倍的評分 _score 。* @param queryString : 要查詢的值 (會對查詢條件進行分詞)* @param analyzer : 選擇分詞器[ik_smart粗粒度,ik_max_word細粒度] 默認:ik_max_word細粒度* @param operator : Operator.OR(并集) [默認] 只要分的詞有一個和索引字段上對應上則就返回* Operator.AND(交集) 分的詞全部滿足的數據返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : queryString 多條件查詢* ?會對查詢條件進行分詞。* ?然后將分詞后的查詢條件和詞條進行等值匹配* ?默認取并集(OR)* ?可以指定多個查詢字段* ?query_string:識別query中的連接符(or 、and)* @Author Mhh* @Date 2021/12/12 19:45*/@Testpublic void queryStringQuery() throws IllegalAccessException, NoSuchFieldException, IOException { // List<AnalyzeResponse.AnalyzeToken> analyzeTokens = elasticsearchSelectController.selectBreakUpText("ik_smart", "black是河北省的");Map<String, Float> fields = new HashMap<>();fields.put("tAddress", (float) 1);fields.put("tEnglishName", (float) 1);List<Teacher> teacherList = elasticsearchSelectController.queryStringQuery(fields,"black是山東省的","ik_smart",Operator.OR,Teacher.class);teacherList.forEach(System.err::println);}}
-
8.14 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must)
-
- must(QueryBuilder queryBuilder)
???????queryBuilder: 查詢語法 包含(term查詢、terms查詢、match查詢、范圍查詢、模糊查詢…)
boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must) 測試
- must(and):條件必須成立
- must和filter配合使用時,max_score(得分)是顯示的
- must 可以是單個條件,也可以對各條件 (默認數組形式)
- maxSore(得分) : 即條件匹配度,匹配度越高,得分越高
- must(QueryBuilder queryBuilder)
-
8.14.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足must子句的條件,并且參與計算分值* // 條件必須成立,性能比filter低。會計算得分* // 對多個查詢條件連接。連接方式:must(and):條件必須成立(會計算得分)* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/@PostMapping("boolQueryBuilderByMust")public <T> List<T> boolQueryBuilderByMust(Map<String, String[]> fields, Class<T> classType) {return elasticsearchSelectService.boolQueryBuilderByMust(fields, classType);} }
?8.14.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足must子句的條件,并且參與計算分值* // 條件必須成立,性能比filter低。會計算得分* // 對多個查詢條件連接。連接方式:must(and):條件必須成立(會計算得分)* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/public <T> List<T> boolQueryBuilderByMust(Map<String, String[]> fields, Class<T> classType);}
?8.14.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足must子句的條件,并且參與計算分值* // 條件必須成立,性能比filter低。會計算得分* // 對多個查詢條件連接。連接方式:must(and):條件必須成立(會計算得分)* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/public <T> List<T> boolQueryBuilderByMust(Map<String, String[]> fields, Class<T> classType) {//構建boolQuery(詞條查詢:對應ES query里的bool)對多個查詢條件連接BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();fields.forEach((key, value1) -> {//查詢條件(詞條查詢:對應ES query里的termQuery)TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(key, value1);//must(and):條件必須成立boolQueryBuilder.must(termsQueryBuilder);});//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must) 測試結果:
- 條件必須成立,性能比filter低。會計算得分
- 可以手動修改得分(得分越高越靠前)
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足must子句的條件,并且參與計算分值* // 條件必須成立,性能比filter低。會計算得分* // 對多個查詢條件連接。連接方式:must(and):條件必須成立(會計算得分)* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/@Testpublic void boolQueryBuilderByMust() {Map<String, String[]> fields = new HashMap<>();fields.put("tAddress", new String[]{"山東省"});fields.put("tEnglishName", new String[]{"black"});fields.put("tAge", new String[]{"15"});List<Teacher> teacherList = elasticsearchSelectController.boolQueryBuilderByMust(fields,Teacher.class);teacherList.forEach(System.err::println);}}
-
8.15 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:filter)
-
- filter(QueryBuilder queryBuilder)
???????queryBuilder: 查詢語法 包含(term查詢、terms查詢、match查詢、范圍查詢、模糊查詢…)
boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:filter) 測試
- filter(and):條件必須成立
- filter : 可以是單個條件,也可以對各條件 (默認數組形式)
- filter : 單獨使用不會計算得分
- filter(QueryBuilder queryBuilder)
-
8.15.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(must:數組中多值是或者的關系,只要是所有字段能對應到數組中至少一個值就可以返回)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足filter子句的條件,但是不會像must一樣,參與計算分值* // 對多個查詢條件連接。連接方式:filter(and):條件必須成立,性能比must高。不會計算得分* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/@PostMapping("boolQueryBuilderByFilter")public <T> List<T> boolQueryBuilderByFilter(Map<String, String[]> fields, Class<T> classType) {return elasticsearchSelectService.boolQueryBuilderByFilter(fields, classType);}}
?8.15.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(must:數組中多值是或者的關系,只要是所有字段能對應到數組中至少一個值就可以返回)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足filter子句的條件,但是不會像must一樣,參與計算分值* // 對多個查詢條件連接。連接方式:filter(and):條件必須成立,性能比must高。不會計算得分* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/public <T> List<T> boolQueryBuilderByFilter(Map<String, String[]> fields, Class<T> classType);}
?8.15.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(must:數組中多值是或者的關系,只要是所有字段能對應到數組中至少一個值就可以返回)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足filter子句的條件,但是不會像must一樣,參與計算分值* // 對多個查詢條件連接。連接方式:filter(and):條件必須成立,性能比must高。不會計算得分* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/public <T> List<T> boolQueryBuilderByFilter(Map<String, String[]> fields, Class<T> classType) {//構建boolQuery(詞條查詢:對應ES query里的bool)對多個查詢條件連接BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();fields.forEach((key, value1) -> {//查詢條件(詞條查詢:對應ES query里的termQuery)TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(key, value1);//must(and):條件必須成立boolQueryBuilder.filter(termsQueryBuilder);});//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:filter) 測試結果:
- filter:條件必須成立,性能比must高。不會計算得分
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** ------boolQuery子句用termsQuery做的測試* // fields: 只要有一條數據包含fields 都包含value數組中的一種就能返回** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(must:數組中多值是或者的關系,只要是所有字段能對應到數組中至少一個值就可以返回)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須滿足filter子句的條件,但是不會像must一樣,參與計算分值* // 對多個查詢條件連接。連接方式:filter(and):條件必須成立,性能比must高。不會計算得分* // maxSore(得分):即條件匹配度,匹配度越高,得分越高* @Author Mhh* @Date 2021/12/13 10:31*/@Testpublic void boolQueryBuilderByFilter() {Map<String, String[]> fields = new HashMap<>();fields.put("tAddress", new String[]{"山東省", "山西省"});fields.put("tEnglishName", new String[]{"black", "green"});fields.put("tAge", new String[]{"15", "24"});List<Teacher> teacherList = elasticsearchSelectController.boolQueryBuilderByFilter(fields,Teacher.class);teacherList.forEach(System.err::println);}}
- filter:條件必須成立,性能比must高。不會計算得分
-
8.16 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must_not)
-
- mustNot(QueryBuilder queryBuilder)
???????queryBuilder: 查詢語法 包含(term查詢、terms查詢、match查詢、范圍查詢、模糊查詢…)
boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must_not) 測試
- must_not(not):條件必須不成立
- must_not : 可以是單個條件,也可以對各條件 (默認數組形式)
- mustNot(QueryBuilder queryBuilder)
-
8.16.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(must_not:只要是所有字段都對應不到數組中的值就可以返回)* //fields 只要數據不包含在 value數組中指定的返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須不滿足定義的條件* // 對多個查詢條件連接。連接方式:must_not(not):條件必須不成立* @Author Mhh* @Date 2021/12/19 18:55*/@PostMapping("boolQueryBuilderByMustNot")public <T> List<T> boolQueryBuilderByMustNot(Map<String, String[]> fields, Class<T> classType) {return elasticsearchSelectService.boolQueryBuilderByMustNot(fields, classType);}}
?8.16.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值* //fields 只要數據不包含在 value數組中指定的返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須不滿足定義的條件* // 對多個查詢條件連接。連接方式:must_not(not):條件必須不成立* @Author Mhh* @Date 2021/12/19 18:55*/public <T> List<T> boolQueryBuilderByMustNot(Map<String, String[]> fields, Class<T> classType);}
?8.16.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值* //fields 只要數據不包含在 value數組中指定的返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須不滿足定義的條件* // 對多個查詢條件連接。連接方式:must_not(not):條件必須不成立* @Author Mhh* @Date 2021/12/19 18:55*/public <T> List<T> boolQueryBuilderByMustNot(Map<String, String[]> fields, Class<T> classType) {//構建boolQuery(詞條查詢:對應ES query里的bool)對多個查詢條件連接BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();fields.forEach((key, value1) -> {//查詢條件(詞條查詢:對應ES query里的termQuery)TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(key, value1);//must(and):條件必須成立boolQueryBuilder.mustNot(termsQueryBuilder);});//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:must_not) 測試結果:
- must_not:返回文檔查詢到不滿足定義的條件
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(must_not:只要是所有字段都對應不到數組中的值就可以返回)* //fields 只要數據不包含在 value數組中指定的返回* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔必須不滿足定義的條件* // 對多個查詢條件連接。連接方式:must_not(not):條件必須不成立* @Author Mhh* @Date 2021/12/19 18:55*/@Testpublic void boolQueryBuilderByMustNot() {Map<String, String[]> fields = new HashMap<>();fields.put("tAddress", new String[]{"山東省"});fields.put("tEnglishName", new String[]{"black"});fields.put("tAge", new String[]{"24", "21"});List<Teacher> teacherList = elasticsearchSelectController.boolQueryBuilderByMustNot(fields,Teacher.class);teacherList.forEach(System.err::println);}}
- must_not:返回文檔查詢到不滿足定義的條件
-
8.17 boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:should)
-
- should(QueryBuilder queryBuilder)
???????queryBuilder: 查詢語法 包含(term查詢、terms查詢、match查詢、范圍查詢、模糊查詢…)
boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:should) 測試
- should(or):條件可以成立
- minimumShouldMatch : 參數定義了至少滿足幾個子句
- should : 可以是單個條件,也可以對各條件 (默認數組形式)
- should(QueryBuilder queryBuilder)
-
8.17.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(should:只要有一條數據對應的字段包含 value數組的值就返回)* // 只要有一條數據對應的字段包含 value數組的值就返回* @param minimumShouldMatch : 參數定義了至少滿足幾個子句* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔可能滿足should子句的條件.* // 在一個bool查詢中,如果沒有must或者filter,有一個或者多個should子句,那么只要滿足一個就可以返回* @Author Mhh* @Date 2021/12/19 19:23*/@PostMapping("boolQueryBuilderByShould")public <T> List<T> boolQueryBuilderByShould(Map<String, String[]> fields, Integer minimumShouldMatch, Class<T> classType) {return elasticsearchSelectService.boolQueryBuilderByShould(fields, minimumShouldMatch, classType);}}
?8.17.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(should:只要有一條數據對應的字段包含 value數組的值就返回)* //只要有一條數據對應的字段包含 value數組的值就返回* @param minimumShouldMatch : 參數定義了至少滿足幾個子句* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔可能滿足should子句的條件.* // 在一個bool查詢中,如果沒有must或者filter,有一個或者多個should子句,那么只要滿足一個就可以返回* @Author Mhh* @Date 2021/12/19 19:23*/public <T> List<T> boolQueryBuilderByShould(Map<String, String[]> fields, Integer minimumShouldMatch, Class<T> classType);}
?8.17.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(should:只要有一條數據對應的字段包含 value數組的值就返回)* //只要有一條數據對應的字段包含 value數組的值就返回* @param minimumShouldMatch : 參數定義了至少滿足幾個子句* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔可能滿足should子句的條件.* // 在一個bool查詢中,如果沒有must或者filter,有一個或者多個should子句,那么只要滿足一個就可以返回* @Author Mhh* @Date 2021/12/19 19:23*/public <T> List<T> boolQueryBuilderByShould(Map<String, String[]> fields, Integer minimumShouldMatch, Class<T> classType) {//構建boolQuery(詞條查詢:對應ES query里的bool)對多個查詢條件連接BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();fields.forEach((key, value1) -> {//查詢條件(詞條查詢:對應ES query里的termQuery)TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(key, value1);//must(and):條件必須成立boolQueryBuilder.should(termsQueryBuilder);});//參數定義了至少滿足幾個子句boolQueryBuilder.minimumShouldMatch(minimumShouldMatch);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?boolQuery 查詢文檔 (對多個查詢條件連接。連接方式:should) 測試結果:
- minimumShouldMatch : 參數定義了至少滿足幾個子句
- minimumShouldMatch=2:表示必須滿足兩個子句才能返回
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** ------boolQuery子句用termsQuery做的測試** @param fields :Map<String,String[]> key:es索引庫里的域(字段名), value數組:一域多值, 查詢的值(should:只要有一條數據對應的字段包含 value數組的值就返回)* // 只要有一條數據對應的字段包含 value數組的值就返回* @param minimumShouldMatch : 參數定義了至少滿足幾個子句* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : boolQuery:返回的文檔可能滿足should子句的條件.* // 在一個bool查詢中,如果沒有must或者filter,有一個或者多個should子句,那么只要滿足一個就可以返回* @Author Mhh* @Date 2021/12/19 19:23*/@Testpublic void boolQueryBuilderByShould() {Map<String, String[]> fields = new HashMap<>();fields.put("tAddress", new String[]{"山西省"});fields.put("tEnglishName", new String[]{"green", "yellow"}); // fields.put("tAge", new String[]{"24"});List<Teacher> teacherList = elasticsearchSelectController.boolQueryBuilderByShould(fields,2,Teacher.class);teacherList.forEach(System.err::println);}}
-
8.18 HighlightBuilder 查詢文檔 (高亮)
-
- new HighlightBuilder().field(String name).preTags(String… preTags).postTags(String… postTags)
?????????????name :????? 要突出顯示(高亮)的字段
?????????????preTags :? 設置將用于突出顯示的預標簽。[前綴]
?????????????postTags : 設置將用于突出顯示的帖子標簽。[后綴]
HighlightBuilder 查詢文檔 (高亮) 測試
實施步驟:
- 高亮查詢:
1. 設置高亮
????????? 高亮字段
??????????前綴
??????????后綴
2. 將高亮了的字段數據,替換原有數據
- new HighlightBuilder().field(String name).preTags(String… preTags).postTags(String… postTags)
-
8.18.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param field : 高亮字段 也是 match要查詢的字段* @param preTags : 高亮前綴* @param postTags : 高亮后綴* @param text : 查詢的值(會分詞)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 給查詢到的值進行高亮* @Author Mhh* @Date 2021/12/21 15:15*/@PostMapping("highlightBuilder")public <T> List<T> highlightBuilder(String field, String preTags, String postTags, String text, Class<T> classType) {return elasticsearchSelectService.highlightBuilder(field, preTags, postTags, text, classType);}}
?8.18.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param field : 高亮字段 也是 match要查詢的字段* @param preTags : 高亮前綴* @param postTags : 高亮后綴* @param text : 查詢的值(會分詞)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 給查詢到的值進行高亮* @Author Mhh* @Date 2021/12/21 15:15*/public <T> List<T> highlightBuilder(String field, String preTags, String postTags, String text, Class<T> classType);}
?8.18.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param field : 高亮字段 也是 match要查詢的字段* @param preTags : 高亮前綴* @param postTags : 高亮后綴* @param text : 查詢的值(會分詞)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 給查詢到的值進行高亮* @Author Mhh* @Date 2021/12/21 15:15*/public <T> List<T> highlightBuilder(String field, String preTags, String postTags, String text, Class<T> classType) {//查詢條件(詞條查詢:對應ES query里的match)MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(field, text);////設置高亮三要素 field: 你的高亮字段 // preTags :前綴 // postTags:后綴HighlightBuilder highlightBuilder = new HighlightBuilder().field(field).preTags(preTags).postTags(postTags);//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(matchQueryBuilder).withHighlightBuilder(highlightBuilder).build();//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();//獲取值返回return search.getSearchHits().stream().map(searchHit -> {//獲得結果實體T content = searchHit.getContent();//所有高亮結果Map<String, List<String>> highlightFields = searchHit.getHighlightFields();//遍歷高亮結果for (Map.Entry<String, List<String>> stringListEntry : highlightFields.entrySet()) {String key = stringListEntry.getKey();//獲取實體反射類Class<?> aClass = content.getClass();try {//獲取該實體屬性Field declaredField = aClass.getDeclaredField(key);//權限為私的 解除!declaredField.setAccessible(true);//替換,把高亮字段替換到這個實體對應的屬性值上declaredField.set(content, stringListEntry.getValue().get(0));} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}return content;}).collect(Collectors.toList());}}
?HighlightBuilder 查詢文檔 (高亮) 測試結果:
- 高亮字段可以是多個,通過鏈式調用接著.field(String name);
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param field : 高亮字段 也是 match要查詢的字段* @param preTags : 高亮前綴* @param postTags : 高亮后綴* @param text : 查詢的值(會分詞)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<T>* @explain : 給查詢到的值進行高亮* @Author Mhh* @Date 2021/12/21 15:15*/@Testpublic void highlightBuilder() {List<Teacher> teacherList = elasticsearchSelectController.highlightBuilder("tAddress","<font color='red'>","</font>","山東省高新區",Teacher.class);teacherList.forEach(System.err::println);}}
- 高亮字段可以是多個,通過鏈式調用接著.field(String name);
-
8.19 AggregationBuilders 查詢文檔 (聚合查詢)
-
- AggregationBuilders.max(String name).field(String field) : 最大值(max)
- AggregationBuilders.min(String name).field(String field) : 最小值(min)
- AggregationBuilders.avg(String name).field(String field) : 平均值(avg)
- AggregationBuilders.terms(String name).field(String field) : 分組(group by)
- AggregationBuilders.sum(String name).field(String field) : 總數(sum)
- …
?????????????name : 給聚合定義名稱
?????????????field :?? 設置用于此聚合的字段。
AggregationBuilders 查詢文檔 (聚合查詢) 測試
- 相當于MySQL的聚合函數。max、min、avg、sum等
- termsAggregationBuilder.subAggregation(AggregationBuilder aggregation) :
????????????????????相當于MySQL的 group by 操作。不要對text類型的數據進行分組,會失敗。
-
8.19.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** @param name : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain : 聚合對數據進行分組的求和,求數,最大值,最小值,或者其它的自定義的統計功能,* // es對聚合有著不錯的支持,需要注意的是,在對某字段進行聚合之后,需要開啟這個字段的fielddata* // 不要對text類型的數據進行分組,會失敗* @Author Mhh* @Date 2021/12/22 14:29*/@PostMapping("aggregationBuilder")public <T> List<T> aggregationBuilder(String name, Class<T> classType, String... values) {return elasticsearchSelectService.aggregationBuilder(name, classType, values);}}
?8.19.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** @param name : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain : 聚合對數據進行分組的求和,求數,最大值,最小值,或者其它的自定義的統計功能,* // es對聚合有著不錯的支持,需要注意的是,在對某字段進行聚合之后,需要開啟這個字段的fielddata* // 不要對text類型的數據進行分組,會失敗* @Author Mhh* @Date 2021/12/22 14:29*/public <T> List<T> aggregationBuilder(String name, Class<T> classType, String... values);}
?8.19.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** @param name : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain : 聚合對數據進行分組的求和,求數,最大值,最小值,或者其它的自定義的統計功能,* // es對聚合有著不錯的支持,需要注意的是,在對某字段進行聚合之后,需要開啟這個字段的fielddata* // 不要對text類型的數據進行分組,會失敗* @Author Mhh* @Date 2021/12/22 14:29*/public <T> List<T> aggregationBuilder(String name, Class<T> classType, String... values) {//構建termsQueryBuilder(詞條查詢:對應ES query里的terms)不分詞查詢TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(name, values);//最大值(max)MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("maxAge").field("tAge");//最小值(min)MinAggregationBuilder minAggregationBuilder = AggregationBuilders.min("minAge").field("tAge");//平均值(avg)AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("avgAge").field("tAge");//分組(group by)TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("termClassName").field("tClassName");//總數(sum)SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("sumAge").field("tAge");//創建查詢條件構建器SearchSourceBuilder(對應ES外面的大括號)NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(termsQueryBuilder).//聚合最大值addAggregation(maxAggregationBuilder).//聚合最小直addAggregation(minAggregationBuilder).//聚合平均值addAggregation(avgAggregationBuilder).//聚合總值addAggregation(sumAggregationBuilder).//分組后聚合 各組的最大值和各組的總和addAggregation(termsAggregationBuilder.subAggregation(maxAggregationBuilder).subAggregation(sumAggregationBuilder)).build();//查詢,獲取查詢結果SearchHits<T> search = elasticsearchRestTemplate.search(nativeSearchQuery, classType);//獲取總記錄數long totalHits = search.getTotalHits();for (Aggregation aggregation : Objects.requireNonNull(search.getAggregations())) {//查詢結果中的總和Sum sum = aggregation instanceof Sum ? ((Sum) aggregation) : null;Optional.ofNullable(sum).ifPresent(s -> System.err.println(aggregation.getName() + ":" + s.getValue()));//查詢結果中的最大值Max max = aggregation instanceof Max ? ((Max) aggregation) : null;Optional.ofNullable(max).ifPresent(s -> System.err.println(aggregation.getName() + ":" + s.getValue()));//查詢結果中的最小值Min min = aggregation instanceof Min ? ((Min) aggregation) : null;Optional.ofNullable(min).ifPresent(s -> System.err.println(aggregation.getName() + ":" + s.getValue()));//查詢結果中的平均值Avg avg = aggregation instanceof Avg ? ((Avg) aggregation) : null;Optional.ofNullable(avg).ifPresent(s -> System.err.println(aggregation.getName() + ":" + s.getValue()));//分組后查詢結果Terms terms = aggregation instanceof Terms ? (Terms) aggregation : null;Optional.ofNullable(terms).ifPresent(s -> System.err.println(aggregation.getName() + ":" + s.getBuckets()));}//獲取值返回return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());}}
?AggregationBuilders 查詢文檔 (聚合查詢) 測試結果:
- 這里獲取分組后的值實在有些繁瑣,為了言簡意賅只打印了分組后class地址。
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param name : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain : 聚合對數據進行分組的求和,求數,最大值,最小值,或者其它的自定義的統計功能,* // es對聚合有著不錯的支持,需要注意的是,在對某字段進行聚合之后,需要開啟這個字段的fielddata* // 不要對text類型的數據進行分組,會失敗* @Author Mhh* @Date 2021/12/22 14:29*/@Testpublic void aggregationBuilder() {List<Teacher> teacherList = elasticsearchSelectController.aggregationBuilder("tAddress",Teacher.class,"山東省");teacherList.forEach(System.err::println);}}
- 這里獲取分組后的值實在有些繁瑣,為了言簡意賅只打印了分組后class地址。
-
8.20 SuggestBuilders查詢文檔 (completionSuggestion—搜索建議補全)
-
- SuggestBuilders.completionSuggestion(String fieldname).prefix(String prefix).skipDuplicates(boolean skipDuplicates)…
????????????????????????????fieldname : 使用fieldName入參進行標題聯想(這里就是索引被@CompletionField注解標注的字段)
????????????????????????????prefix :?? 設置要為其提供補全的前綴。前綴由建議分析器進行分析。
????????????????????????????skipDuplicates :?? 是否應過濾重復項。默認為 { false}
SuggestBuilders查詢文檔 (completionSuggestion—搜索建議補全) 測試
- 完成補全單詞,輸出如前半部分,補全整個單詞
- SuggestBuilders.completionSuggestion(String fieldname).prefix(String prefix).skipDuplicates(boolean skipDuplicates)…
-
8.20.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** 速度快 輸入的內容立即返回 對字段類型要求多節省存儲空間 時間復雜度O(1),做建議不做糾錯* 感覺和prefixQuery 前綴查詢 差不多.....* <p>* 搜索補全必須定義 這個屬性(* // @CompletionField(analyzer = "ik_smart", searchAnalyzer = "ik_smart", maxInputLength = 100)* // private Completion completion;)* // 給Completion屬性賦值: new Completion(new String[]{"山東省泰安市岱岳區"}))* // :里面的值就是被自動補全的值** @param fieldName : 要用哪個字段進行標題聯想(必須是這個@CompletionField注解所標注的類型為Completion的字段名)* @param text : 被補全的值(比如傳的是山東 可能就能給補全為 山東省)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 搜索補全功能 比如在輸入框輸入(天上)下面就自動補全 (天上人間)(天上邊的彩霞)(....)* @Author Mhh* @Date 2021/12/22 16:51*/@PostMapping("completionSuggestion")public List<String> completionSuggestion(String fieldName, String text, Class<?> classType) {return elasticsearchSelectService.completionSuggestion(fieldName, text, classType);}}
?8.20.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** 速度要快 輸入的內容立即返回 對字段類型要求多節省存儲空間 時間復雜度O(1),做建議不做糾錯* 感覺和prefixQuery 前綴查詢 差不多.....* <p>* 搜索補全必須定義 這個屬性(* // @CompletionField(analyzer = "ik_smart", searchAnalyzer = "ik_smart", maxInputLength = 100)* // private Completion completion;)* // 給Completion屬性賦值: new Completion(new String[]{"山東省泰安市岱岳區"}))* // :里面的值就是被自動補全的值** @param fieldName : 要用哪個字段進行標題聯想(必須是這個@CompletionField注解所標注的類型為Completion的字段名)* @param text : 被補全的值(比如傳的是山東 可能就能給補全為 山東省)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 搜索補全功能 比如在輸入框輸入(天上)下面就自動補全 (天上人間)(天上邊的彩霞)(....)* @Author Mhh* @Date 2021/12/22 16:51*/public List<String> completionSuggestion(String fieldName, String text, Class<?> classType);}
?8.20.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** 速度要快 輸入的內容立即返回 對字段類型要求多節省存儲空間 時間復雜度O(1),做建議不做糾錯* 感覺和prefixQuery 前綴查詢 差不多.....* <p>* 搜索補全必須定義 這個屬性(* // @CompletionField(analyzer = "ik_smart", searchAnalyzer = "ik_smart", maxInputLength = 100)* // private Completion completion;)* // 給Completion屬性賦值: new Completion(new String[]{"山東省泰安市岱岳區"}))* // :里面的值就是被自動補全的值** @param fieldName : 要用哪個字段進行標題聯想(必須是這個@CompletionField注解所標注的類型為Completion的字段名)* @param text : 被補全的值(比如傳的是山東 可能就能給補全為 山東省)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 搜索補全功能 比如在輸入框輸入(天上)下面就自動補全 (天上人間)(天上邊的彩霞)(....)* @Author Mhh* @Date 2021/12/22 16:51*/public List<String> completionSuggestion(String fieldName, String text, Class<?> classType) {//定義反參容器List<String> stringList = new ArrayList<>();//構建搜索建議補全對象CompletionSuggestionBuilder completionSuggestionBuilder = SuggestBuilders.completionSuggestion(fieldName). // 使用fieldName入參進行標題聯想(這里就是索引被@CompletionField注解標注的字段)prefix(text). // 關鍵字(參數傳此)skipDuplicates(true)// 重復過濾//.size(100) // 匹配數量;//創建搜索提示對象 進行封裝搜索補全SuggestBuilder suggestBuilder = new SuggestBuilder();// completionSuggestionBuilder:隨便起的搜索補全的名字suggestBuilder.addSuggestion("completionSuggestionBuilder", completionSuggestionBuilder);//查詢es并反參SearchResponse searchResponse = elasticsearchRestTemplate.suggest(suggestBuilder, elasticsearchRestTemplate.getIndexCoordinatesFor(classType));//獲取反參中的搜索補全結果Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> suggestionBuilder = searchResponse.getSuggest().getSuggestion("completionSuggestionBuilder");// 處理返回List<String> suggests = suggestionBuilder.getEntries().stream().map(x -> x.getOptions().stream().map(y -> y.getText().toString()).collect(Collectors.toList())).findFirst().get();// 將搜索補全內容保存到容器返回for (String suggest : suggests) {stringList.add(suggest);System.err.println("suggest = " + suggest);}return stringList;}}
?SuggestBuilders查詢文檔 (completionSuggestion—搜索建議補全) 測試結果:
- 標題聯想必須是被@CompletionField注解所標注的類型為Completion對象的屬性。
- 定義對象關鍵詞索引 要完成補全搜索,必須要用到特殊的數據類型completion。
- 建議補全的值都是在存儲時保存在completion里的值。
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** @param name : es里索引的域(字段名)* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @param values : 一域多值, 查詢的值* @return java.util.List<T>* @explain : 聚合對數據進行分組的求和,求數,最大值,最小值,或者其它的自定義的統計功能,* // es對聚合有著不錯的支持,需要注意的是,在對某字段進行聚合之后,需要開啟這個字段的fielddata* // 不要對text類型的數據進行分組,會失敗* @Author Mhh* @Date 2021/12/22 14:29*/@Testpublic void aggregationBuilder() {List<Teacher> teacherList = elasticsearchSelectController.aggregationBuilder("tAddress",Teacher.class,"山東省");teacherList.forEach(System.err::println);}}
-
8.21 SuggestBuilders查詢文檔 (termSuggestion—糾錯補全)
-
- SuggestBuilders.termSuggestion(String fieldname).text(String text)…
????????????????????????????fieldname : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。(Keyword字段)
????????????????????????????text:?? 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來
SuggestBuilders查詢文檔 (termSuggestion—糾錯補全) 測試
- 糾錯補全,輸入錯誤的情況下補全正確的單詞
- SuggestBuilders.termSuggestion(String fieldname).text(String text)…
-
8.21.1 Controller層
-
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞條建議器(term suggester)對用戶搜索的內容做糾正幫助用戶搜索到精確度高的關鍵字** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞條建議器(term suggester)主要做糾正 但是是短語就不能做了(Keyword字段)* // 用在查詢用戶中心查詢人名上* // 例如:查詢 孟浩號 而在字段中是孟浩浩 則就建議返回了 孟浩浩* @Author Mhh* @Date 2021/12/23 15:40*/@PostMapping("termSuggestion")public List<String> termSuggestion(String fieldName, String text, Class<?> classType) {return elasticsearchSelectService.termSuggestion(fieldName, text, classType);}}
?8.21.2 service層
import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞條建議器(term suggester)對用戶搜索的內容做糾正幫助用戶搜索到精確度高的關鍵字** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞條建議器(term suggester)主要做糾正 但是是短語就不能做了(Keyword字段)* // 用在查詢用戶中心查詢人名上* // 例如:查詢 孟浩號 而在字段中是孟浩浩 則就建議返回了 孟浩浩* @Author Mhh* @Date 2021/12/23 15:40*/public List<String> termSuggestion(String fieldName, String text, Class<?> classType);}
?8.21.3 serviceimpl層
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞條建議器(term suggester)對用戶搜索的內容做糾正幫助用戶搜索到精確度高的關鍵字** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞條建議器(term suggester)主要做糾正 但是是短語就不能做了(Keyword字段)* // 用在查詢用戶中心查詢人名上* // 例如:查詢 孟浩號 而在字段中是孟浩浩 則就建議返回了 孟浩浩* @Author Mhh* @Date 2021/12/23 15:40*/public List<String> termSuggestion(String fieldName, String text, Class<?> classType) {//定義反參容器List<String> stringList = new ArrayList<>(); // 構建糾正詞條對象 詞條建議器(只要是詞,短的 比如姓名)TermSuggestionBuilder termSuggestionBuilder = SuggestBuilders.termSuggestion(fieldName).text(text); /* termSuggestionBuilder.suggestMode(TermSuggestionBuilder.SuggestMode.ALWAYS);/*建議模式(控制提供建議詞的方式):1. missing:默認方式,僅在‘要搜索詞項’不在索引中存在時,才提供建議詞;2. popular:僅提供頻率比‘要搜索詞項’高的建議詞;3. always:總是提供建議詞;*/termSuggestionBuilder.sort(SortBy.SCORE); /*建議詞的排序方式:1. score:先按評分排序,再按文檔頻率、term順序排;2. frequency:先按文檔頻率排序,再按評分、term順序排*///創建搜索提示對象 進行封裝詞條糾正SuggestBuilder suggestBuilder = new SuggestBuilder();// termSuggestionBuilder:隨便起的搜索補全的名字(后面會用到)suggestBuilder.addSuggestion("termSuggestionBuilder", termSuggestionBuilder);//查詢,獲取查詢結果SearchResponse searchResponse = elasticsearchRestTemplate.suggest(suggestBuilder, IndexCoordinates.of(classType.getAnnotation(Document.class).indexName()));//獲取反參中的詞條糾正結果Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> suggestionBuilder = searchResponse.getSuggest().getSuggestion("termSuggestionBuilder");// 處理返回List<String> suggests = suggestionBuilder.getEntries().stream().map(x -> x.getOptions().stream().map(y -> y.getText().toString()).collect(Collectors.toList())).findFirst().get();// 將詞條糾正內容保存到容器返回for (String suggest : suggests) {stringList.add(suggest);System.err.println("suggest = " + suggest);}return stringList;}}
?SuggestBuilders查詢文檔 (termSuggestion—糾錯補全) 測試結果:
- 對用戶搜索的內容做糾正幫助用戶搜索到精確度高的關鍵字
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞條建議器(term suggester)對用戶搜索的內容做糾正幫助用戶搜索到精確度高的關鍵字** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞條建議器(term suggester)主要做糾正 但是是短語就不能做了(Keyword字段)* // 用在查詢用戶中心查詢人名上* // 例如:查詢 孟浩號 而在字段中是孟浩浩 則就建議返回了 孟浩浩* @Author Mhh* @Date 2021/12/23 15:40*/@Testpublic void termSuggestion() {List<String> stringList = elasticsearchSelectController.termSuggestion("tName","小黃教授",Teacher.class);stringList.forEach(System.err::println);}}
- 對用戶搜索的內容做糾正幫助用戶搜索到精確度高的關鍵字
-
8.22 SuggestBuilders查詢文檔 (phraseSuggestion—糾錯補全) -
- SuggestBuilders.phraseSuggestion(String fieldname).text(String text)…
????????????????????????????fieldname : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。(Keyword字段)
????????????????????????????text:?? 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來
SuggestBuilders查詢文檔 (termSuggestion—糾錯補全) 測試實在是研究不出它與termSuggestione 有啥區別(后期再補充它)
- 自動糾錯補全短語,輸入一個單詞糾錯補全整個短語
- SuggestBuilders.phraseSuggestion(String fieldname).text(String text)…
-
8.22.1 Controller層 -
import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢類*/ @RestController @RequestMapping("/elasticSearch/select") public class ElasticsearchSelectController {@Autowiredprivate ElasticsearchSelectService elasticsearchSelectService;/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞組建議器(phraseSuggestion)** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞組建議器(phraseSuggestion)適合較長的字段,但是也不是萬能的 做糾正(Keyword字段)* @Author Mhh* @Date 2021/12/23 15:40*/@PostMapping("phraseSuggestion")public List<String> phraseSuggestion(String fieldName, String text, Class<?> classType) {return elasticsearchSelectService.phraseSuggestion(fieldName, text, classType);}}
?8.22.2 service層import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.springframework.data.domain.Sort;import java.io.IOException; import java.util.List; import java.util.Map;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述: 查詢*/ public interface ElasticsearchSelectService {/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞組建議器(phraseSuggestion)** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞組建議器(phraseSuggestion)適合較長的字段,但是也不是萬能的 做糾正(Keyword字段)* @Author Mhh* @Date 2021/12/23 15:40*/public List<String> phraseSuggestion(String fieldName, String text, Class<?> classType);}
?8.22.3 serviceimpl層import com.it.mhh.elasticsearch.service.ElasticsearchSelectService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.*; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.suggest.*; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service;import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @Service public class ElasticsearchSelectServiceImp implements ElasticsearchSelectService {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞組建議器(phraseSuggestion)** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞組建議器(phraseSuggestion)適合較長的字段,但是也不是萬能的 做糾正(Keyword字段)* @Author Mhh* @Date 2021/12/23 15:40*/public List<String> phraseSuggestion(String fieldName, String text, Class<?> classType) {//定義反參容器List<String> stringList = new ArrayList<>(); // 構建糾正詞組對象PhraseSuggestionBuilder phraseSuggestionBuilder = SuggestBuilders.phraseSuggestion(fieldName).text(text);//創建搜索提示對象 進行封裝詞條糾正SuggestBuilder suggestBuilder = new SuggestBuilder();// phraseSuggestionBuilder:隨便起的搜索補全的名字(后面會用到)suggestBuilder.addSuggestion("phraseSuggestion", phraseSuggestionBuilder);//查詢,獲取查詢結果SearchResponse searchResponse = elasticsearchRestTemplate.suggest(suggestBuilder, IndexCoordinates.of(classType.getAnnotation(Document.class).indexName()));//獲取反參中的詞條糾正結果Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> suggestionBuilder = searchResponse.getSuggest().getSuggestion("phraseSuggestion");// 處理 返回List<String> suggests = suggestionBuilder.getEntries().stream().map(x -> x.getOptions().stream().map(y -> y.getText().toString()).collect(Collectors.toList())).findFirst().get();// 將詞條糾正內容保存到容器返回for (String suggest : suggests) {stringList.add(suggest);System.err.println("suggest = " + suggest);}return stringList;}}
?SuggestBuilders查詢文檔 (termSuggestion—糾錯補全) 測試結果:- 適合較長的字段,但是也不是萬能的 做糾正
import com.it.mhh.elasticsearch.controller.ElasticsearchSelectController; import com.it.mhh.elasticsearch.entity.Student; import com.it.mhh.elasticsearch.entity.Teacher; import org.elasticsearch.client.indices.AnalyzeResponse; import org.elasticsearch.index.query.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException; import java.util.*;/*** @創建人: Mhh* @創建時間: 2021/12/10* @描述:*/ @SpringBootTest @RunWith(SpringRunner.class) public class ElasticsearchSelectControllerTest {@Autowiredprivate ElasticsearchSelectController elasticsearchSelectController;//es的查詢/*** https://www.cnblogs.com/Alexephor/p/11408446.html(Elasticsearch之建議器suggester)寫的很詳細* 詞組建議器(phraseSuggestion)** @param fieldName : 從fieldName字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。Keyword字段* @param text : 建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。* @param classType : 返回的list里的對象并且通過對象里面@Document注解indexName屬性獲取查詢哪個索引* @return java.util.List<java.lang.String>* @explain : 詞組建議器(phraseSuggestion)適合較長的字段,但是也不是萬能的 做糾正(Keyword字段)* @Author Mhh* @Date 2021/12/23 15:40*/@Testpublic void phraseSuggestion() {List<String> stringList = elasticsearchSelectController.phraseSuggestion("tFamous","吾之初心永世不完",Teacher.class);stringList.forEach(System.err::println);}}
- 適合較長的字段,但是也不是萬能的 做糾正