springboot集成ES
- 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);}}
- 适合较长的字段,但是也不是万能的 做纠正
相关文章:

springboot集成ES
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 ser…...
Maven 生成编译时间和版本Java类
本文使用Maven插件来自动生成一个 Version.java 类,可以在Java代码中使用里面对应的常量,获取当前版本号和构建时间。 Maven编译后自动生成的 Version.java 文件内容如下所示: package com.shanhy.demo;public final class Version {public…...
关于uniapp微信小程序scroll-view组件使用show-scrollbar隐藏不了滚动条
这里关于使用 scroll-view组件 时候有滚动条 想要隐藏滚动条但是使用show-scrollbar没有效果 这时候又使用类名隐藏滚动条 使用id隐藏滚动条都不行 解决方法:在使用 scroll-view组件 的页面或者app 页面加上以下代码就可以了 ::-webkit-scrollbar {displa…...

CSS:filter滤镜 详解(用法 + 代码 + 例子 + 效果)
文章目录 filter 滤镜blur() 模糊度例子 渐变光晕 brightness() 元素亮度contrast() 对比度grayscale() 元素灰度hue-rorate() 色相opacity() 透明度invert() 反转颜色saturate() 饱和度 backdrop-filter 蒙版,滤镜例子 卷轴展开 filter 滤镜 动图为效果添加前后对…...

【Unity每日一记】Physics.Raycast 相关_Unity中的“X光射线”
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:uni…...

软件报错msvcr90.dll丢失的解决方法,亲测可以修复
我曾经遇到过一个令人头疼的问题:msvcr90.dll丢失。这个问题导致了我的程序无法正常运行,让我感到非常苦恼。然而,在经过一番努力后,我终于成功地修复了这个问题,这让我感到非常欣慰和满足。 msvcr90.dll丢失的原因可能…...
第一百一十八回 如何获取蓝牙连接状态
文章目录 知识回顾实现方法示例代码我们在上一章回中介绍了如何连接蓝牙设备相关的内容,本章回中将介绍如何获取蓝牙连接状态.闲话休提,让我们一起Talk Flutter吧。 知识回顾 我们在上一章回中介绍如何连接蓝牙设备,但是如何知道蓝牙设备是否连接成功呢?这就需要我们去获取…...
C++11并发与多线程笔记(12) windows临界区、其他各种mutex互斥量
C11并发与多线程笔记(12) windows临界区、其他各种mutex互斥量 1、windows临界区2、自动析构技术3、递归独占互斥量 std::recursive_mutex4、带超时的互斥量 std::timed_mutex 和 std::recursive_timed_mutex4.1 std::timed_mutex:是带超时的…...

[MAUI]在.NET MAUI中实现可拖拽排序列表
文章目录 创建可拖放控件创建绑定服务类拖拽(Drag)拖拽悬停,经过(DragOver)释放(Drop) 创建页面元素最终效果项目地址 .NET MAUI 中提供了拖放(drag-drop)手势识别器,允许用户通过拖…...
Linux 内核内存管理 pfn_to_online_page宏
文章目录 一、Memory Hotplug1.1 简介1.2 热插拔事件通知机制 二、pfn_to_online_page2.1 pfn_to_online_page2.2 pfn_to_section_nr2.3 online_section_nr 参考资料 一、Memory Hotplug 1.1 简介 Linux 内存热插拔(Memory Hotplug)是指在运行时动态增…...

『C语言初阶』第八章 -结构体
前言 今天小羊又来给铁汁们分享关于C语言的结构体,在C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型),今天我们主要简单了解一下结构体。 一、结构体是什么&#x…...
chatgpt汇编,两个关于chatgpt的问题
1.用C写一个高级的可自主学习的AI语言模型 编写一个高级的可自主学习的AI语言模型是一个复杂且庞大的工程,需要深入的专业知识和大量的时间精力。下面是一个简化的示例,演示如何使用C实现一个基本的可自主学习的AI语言模型。 首先,你需要定…...

ps丢失d3dcompiler_47.dll怎么办,启动无反应,分享三个解决方法
d3dcompiler_47.dll64位是windows系统中重要的dll文件,缺少了它可能会引起部分软件或者游戏不能运行。 如果系统出现“找不到d3dcompiler_47.dll”或“d3dcompiler_47.dll丢失”等错误信息,那么我们就该着手修复它。 先带了解一下d3dcompiler_47.dll是什…...

第三章nginx详解
nginx:高性能,轻量级的web服务软件。 特点: 1,稳定性高。(没有apache稳定) 2,系统资源消耗地较低。(处理http请求的并发能力非常高,单台物理服务器可以处理30000-5000…...

【二叉树前沿篇】树
【二叉树前沿篇】树 1 树的概念2. 树的相关概念3. 树的表示4. 树在实际中的运用(表示文件系统的目录树结构) 1 树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是…...

python3 0基础学习----数据结构(基础+练习)
python 0基础学习笔记之数据结构 📚 几种常见数据结构列表 (List)1. 定义2. 实例:3. 列表中常用方法.append(要添加内容) 向列表末尾添加数据.extend(列表) 将可迭代对象逐个添加到列表中.insert(索引,插入内容) 向指定…...
计算机科学中的“旅行商问题”
题目:旅行商问题(Traveling Salesman Problem) 当初为何收藏:我收藏了这个题目是因为它是一个经典而富有挑战性的组合优化问题,涉及到计算机科学、算法设计和实际应用领域。我认为这个问题可以展示出算法设计的重要性…...

QT:自定义控件(Connect使用,子控件连接)
自定义控件封装: 1.添加新文件(设计师界面类),创建子页面 ,放自己想要的控件 2.在主页面中使用子控件 :新建一个widget- ISO21434 组织网络安全管理(二) ISO21434 项目网络安全管理(三) ISO21434 分布式网络安全(四) SO21434 持续进行的网络安全(五) ISO21434 概念阶段网络安全(六)...

Visual Studio 如何放大代码字体的大小
1.打开Visual Studio,新建一个程序,一段代码,为接下去的操作做好准备。单击菜单栏的【工具】选项。 2.在跳出来菜单中找到【选项】(一般在最后一项),然后单击。跳出新的窗口。 3.跳出新的窗口后ÿ…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...

使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...

鸿蒙Navigation路由导航-基本使用介绍
1. Navigation介绍 Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示(Nav…...