创建索引
在elasticsearch中创建students索引
PUT /students{"settings": {"number_of_shards": 3,"number_of_replicas": 2,"index.max_ngram_diff":30,"analysis": {"analyzer": {"ngram_analyzer": {"tokenizer": "ngram_tokenizer"}},"tokenizer": {"ngram_tokenizer": {"type": "ngram","min_gram": 1,"max_gram": 30,"token_chars": ["letter","digit"]}}}},"mappings": {"properties": {"id": {"type": "long"},"name": {"type": "text","analyzer": "ngram_analyzer"},"gender": {"type": "keyword"},"birthDate": {"type": "date","format": "yyyy-MM-dd"}}}}
创建项目
添加依赖
使用java操作Elasticsearce需要添加spring-boot-starter-data-elasticsearch依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>cn.tedu</groupId><artifactId>Elasticsearch</artifactId><version>0.0.1-SNAPSHOT</version><name>Elasticsearch</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.2.RELEASE</version></plugin></plugins></build></project>
配置yml连接Elasticsearch
spring:elasticsearch:rest:uris:- http://192.168.64.181:9200- http://192.168.64.181:9201- http://192.168.64.181:9202logging:level:tracer: trace
创建Student类
@Document(indexName = "students", shards = 3, replicas = 2)@Data@NoArgsConstructor@AllArgsConstructor@Accessors(chain = true)public class Student {/*** 使用学号作为索引id*/@Idprivate Long id;private String name;private Character gender;/*** es索引中的字段名,使用Field注解指定,与变量名同名可以省略*/@Field("birthDate")private String birthDate;}
注解及参数说明
@Document():标识要持久化到 Elasticsearch 的域对象shards:索引indexName()的分片数。 用于创建索引。默认为1.replicas:索引indexName()的副本数。 用于创建索引。默认为1.- `refreshInterval:索引indexName()刷新间隔,默认为1s.
indexStoreType:索引indexName()索引存储类型,indexName索引名称,命名要求如下:- 仅小写
- , |, (空格字符), ,, #/li>
- 不能以 -、_、+ 开头
- 不可能是 。 或者 ..
- 不能超过 255 个字节(注意它是字节,因此多字节字符将更快地计入 255 个限制)
@Id:标识该属性为id,在 Elasticsearch 中创建文档时,使用 @Id 注解的字段作为文档的_id值@Field:设置字段的数据类型和其他属性。
创建StudentRepository接口继承ElasticsearchRepository接口
Spring Data 的 Repository 接口提供了一种声明式的数据操作规范,无序编写任何代码,只需遵循 Spring Data 的方法定义规范即可完成数据的 CRUD 操作。spring data es repository API只需要定义接口继承ElasticsearchRepository,基础增删改查方法,在父接口中已定义。可以通过继承ElasticsearchRepository接口添加自定义的数据操作方法。
Repository 方法命名规范
https://www.yuque.com/yiquanchaoren-dvwhg/javassm/arwhgdvgif4s?inner=HoIhB
public interface StudentRepository extends ElasticsearchRepository<Student, Long> {/*** 在name字段搜索关键词** @param key 搜索使用的关键词* @return {@link List}<{@link Student}> 学生信息列表*/List<Student> findByName(String key);/*** 在name字段中搜索关键词,或者使用birthDate字段匹配指定日期** @param name 名字* @param birthDate 出生日期* @return {@link List}<{@link Student}> 符合要求的学生信息*/List<Student> findByNameOrBirthDate(String name, String birthDate);}
进行测试
@SpringBootTestpublic class Test01 {private final StudentRepository studentRepository;@Autowiredpublic Test01(StudentRepository studentRepository) {this.studentRepository = studentRepository;}@Testpublic void test1() {//在es服务器的students索引中保存学生信息studentRepository.save(new Student(1001L, "马大钊", '女', "0659-11-04"));studentRepository.save(new Student(1002L, "马二钊", '女', "0659-11-05"));studentRepository.save(new Student(1003L, "马三钊", '女', "0659-11-06"));studentRepository.save(new Student(1004L, "马四钊", '女', "0659-11-07"));studentRepository.save(new Student(1005L, "马五钊", '女', "0659-11-08"));studentRepository.save(new Student(1006L, "马六钊", '女', "0659-11-09"));studentRepository.save(new Student(1007L, "马七钊", '女', "0659-11-10"));studentRepository.save(new Student(1008L, "马小钊", '女', "0659-11-11"));}@Testpublic void test2() {studentRepository.save(new Student(1001L, "马王堆", '?', "0023-11-04"));}@Testpublic void test3() {Optional<Student> stu = studentRepository.findById(1001L);//判断Optional对象中是否存在Student对象if (stu.isPresent()) {System.out.println("-------------------------------" + stu + "---------------------------------");}Iterable<Student> students = studentRepository.findAll();for (Student student : students) {System.out.println(student);}}@Testpublic void test4() {studentRepository.deleteById(1008L);}@Testpublic void test5() {List<Student> studentList = studentRepository.findByName("马王");for (Student student : studentList) {System.out.println(student);}}@Testpublic void test6() {List<Student> students = studentRepository.findByNameOrBirthDate("堆", "0659-11-05");for (Student student : students) {System.out.println(student);}}}
使用 Criteria 构建自定义查询
Criteria数据查询
- 使用Criteria封装搜索条件
- CriteriaQuery封装Criteria条件对象和分页参数
- 注入
ElasticsearchOperations对象进行查询
创建Criteria查询类
@Componentpublic class StudentSearch {private final ElasticsearchOperations operations;@Autowiredpublic StudentSearch(ElasticsearchOperations operations) {this.operations = operations;}/*** 按名称搜索** @param key 关键* @return {@link List}<{@link Student}> 符合条件的学生列表*/public List<Student> searchByName(String key) {Criteria criteria = new Criteria("name");//设置条件criteria.is(key);return exec(criteria);}private List<Student> exec(Criteria criteria) {//将搜索条件封装之Query对象CriteriaQuery query = new CriteriaQuery(criteria);List<Student> list = new ArrayList<>();/*使用ElasticsearchOperations工具类执行查询,需要进行依赖注入SearchHit对象中包含学生数据,相关度得分*/SearchHits<Student> search = operations.search(query, Student.class);for (SearchHit<Student> searchHit : search) {Student stu = searchHit.getContent();list.add(stu);}return list;}/*** 根据出生日期进行搜索** @param from 开始日期* @param to 结束日期* @return {@link List}<{@link Student}> 符合条件的学生列表*/public List<Student> searchByBirthDate(String from, String to) {Criteria criteria = new Criteria("birthDate");criteria.between(from, to);return exec(criteria);}}
进行测试
@SpringBootTestpublic class Test02 {private final StudentSearch search;@Autowiredpublic Test02(StudentSearch search) {this.search = search;}@Testpublic void test1(){List<Student> list = search.searchByName("马");for (Student student : list) {System.out.println(student);}}@Testpublic void test2(){List<Student> list = search.searchByBirthDate("0001-01-01", "2021-11-04");for (Student student : list) {System.out.println(student);}}}
Criteria分页查询和高亮
分页
- Pageable—-向服务器提交的分页参数,page(页数),size(每页的记录数)
- Page ————从服务器返回的一页数据,数据列表,分页信息(可选,可直接使用List<?>)
Repository
Page<Student> findByName(String key, Pageable pageable);
Criteria
Criteria criteria = new Criteria(args);CriteriaQuery query = new CriteriaQuery(criteria);query.setPageable(pageable);
创建接口
public interface StudentRepository extends ElasticsearchRepository<Student, Long> {/*** 在name字段中搜索关键词,或者使用birthDate字段匹配指定日期进行分页查询** @param name 名字* @param birthDate 出生日期* @param pageable 分页参数* @return {@link List}<{@link Student}>*/Page<Student> findByNameOrBirthDate(String name, String birthDate, Pageable pageable);}
进行测试
@SpringBootTestpublic class Test01 {private final StudentRepository studentRepository;@Autowiredpublic Test01(StudentRepository studentRepository) {this.studentRepository = studentRepository;}@Testpublic void test7() {Pageable pageable = PageRequest.of(1, 2);Page<Student> students = studentRepository.findByNameOrBirthDate("马", "0659-11-05", pageable);System.out.println("共有几页:" + students.getTotalPages());System.out.println("是否有上一页:" + students.hasPrevious());System.out.println("是否有下一页:" + students.hasNext());System.out.println("每页大小:" + students.getNumber());for (Student student : students) {System.out.println(student);}}}
