1. 概述
-
Spring Data Elasticsearch 对原生的 Elasticsearch 简化
-
特点:
- 基于Configuration配置,只要在yml文件中配置,项目就可以使用
- 工具类 ElasticsearchTemplate ES模板,类似女通用mapper,通过对象操作ES
- 提供持久层接口 Repository,无需编写基本操作代码(蕾西与mybatis,根据接口自动得到实现),也支持自定义查询
2. 环境搭建
-
步骤一: 修改pom.xml文件,导入坐标
-
步骤二: 修改yml文件,添加Elasticsearch配置信息
-
步骤三: 创建一个配置类,项目启动时时,设置一个参数,防止运行时异常
-
步骤四: 编写测试方法
-
步骤一: 修改pom.xml文件,导入坐标
<dependencies> <!--redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <!--测试--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>com.czxy</groupId> <artifactId>changgou_common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--es--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> </dependencies>
-
步骤二: 修改yml文件,添加Elasticsearch配置信息
spring: redis: database: 1 #确定使用库 host: 127.0.0.1 #redis服务地址 port: 6379 #redis 端口号 data: elasticsearch: cluster-name: elasticsearch cluster-nodes: 127.0.0.1:9300
-
步骤三: 创建一个配置类,项目启动时时,设置一个参数,防止运行时异常
package com.czxy.config; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; /** * Created by Pole丶逐. */ @Configuration public class ESConfig { /** * 项目启动时,设置一个参数 */ @PostConstruct public void init() { System.setProperty("es.set.netty.runtime.available.processors", "false"); } }
-
步骤四: 编写测试方法
package com.czxy.test; import com.czxy.TestApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * [@Author](https://my.oschina.net/arthor) Pole丶逐 * [@Date](https://my.oschina.net/u/2504391) 2020/4/13 20:39 * [@E-mail](https://my.oschina.net/rosolio) */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class Demo01 { @Test public void test(){ System.out.println("AAA"); } }
3. 索引操作
3.1 创建映射类
-
映射类: 用于表示java数据和Elasticsearch中数据对应关系.在Spring Data Elasticsearch使用注解完成
名称 修饰位置 参数 @Document 表示java数据和Elasticsearch中数据对应关系 indexName: 对应索引名称<br/>type: 对应索引库中的类型 <br/>shards: 分片数量 <br/>replicas: 副本数量 @Id 唯一标识 无 @Field java属性和es字段的对应关系 type: 字段类型<br/>analyzer: 分词器名称<br/>index: 是否索引,默认为true<br/>store: 是否存储,默认为false -
实现类:
package com.czxy.vo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; /** * @Author Pole丶逐 * @Date 2020/4/13 20:55 * @E-mail */ @NoArgsConstructor @AllArgsConstructor @Data @Document(indexName = "czxy56",type = "book",shards = 4,replicas = 2) public class ESBook { @Id private Long id; @Field(type = FieldType.Text,analyzer = "ik_max_word") private String title; @Field(type = FieldType.Keyword) private String images; @Field(type = FieldType.Float) private Double price; }
3.2 创建索引,添加映射,删除索引
-
ElasticsearchTemplate工具类提供对应方法完成以下功能
-
步骤一: 直接注入ElasticsearchTemplate,spring容器中自动创建
-
步骤二: 调用对应API操作
package com.czxy.test; import com.czxy.TestApplication; import com.czxy.vo.ESBook; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; /** * @Author Pole丶逐 * @Date 2020/4/13 21:00 * @E-mail */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestES { @Resource private ElasticsearchTemplate elasticsearchTemplate; @Test public void test1(){ // 创建索引 elasticsearchTemplate.createIndex(ESBook.class); } @Test public void test2(){ //创建映射 elasticsearchTemplate.putMapping(ESBook.class); } @Test public void test3(){ //删除索引 elasticsearchTemplate.deleteIndex(ESBook.class); } }
4. 文档操作(增删改)
-
实现接口: ElasticsearchRepository,实现了所有功能
-
只需要继承 **ElasticsearchRepository **接口即可,Spring Data 自动加载
-
参数类型: 泛型
-
第一个: 映射类(ESBook)
-
第二个: 映射类唯一标识的类型(Id)
package com.czxy.repository; import com.czxy.vo.ESBook; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; /** * @Author Pole丶逐 * @Date 2020/4/13 21:15 * @E-mail */ public interface ESBookRepository extends ElasticsearchRepository<ESBook,Long> { }
-
4.1 添加数据
方法名 | 描述 |
---|---|
save() | 添加一个数据 |
saveAll() | 添加一组数据 |
package com.czxy.test;
import com.czxy.TestApplication;
import com.czxy.repository.ESBookRepository;
import com.czxy.vo.ESBook;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
/**
* @Author Pole丶逐
* @Date 2020/4/13 21:14
* @E-mail
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class TestESData {
@Resource
private ESBookRepository esBookRepository;
@Test
public void test1(){
//添加一个数据
esBookRepository.save(new ESBook(1L,"时间简史","01.jpg",35.0));
}
@Test
public void test2(){
ArrayList<ESBook> eslist = new ArrayList<>();
eslist.add(new ESBook(1L,"时间简史","01.jpg",35.0));
eslist.add(new ESBook(2L,"三体","02.jpg",40.0));
eslist.add(new ESBook(3L, "人类简史","03.jpg",35.5));
//添加一个集合
esBookRepository.saveAll(eslist);
}
}
4.2 修改数据
-
修改和添加使用的是一个方法
- 如果id存在则为修改
- 如果id不存在则为添加
@Test public void test1(){ //修改数据,id必须存在,否则为添加 esBookRepository.save(new ESBook(1L,"空间简史","01.jpg",35.0)); }
4.2 删除数据
@Test
public void test3(){
// 根据对象删除
//esBookRepository.delete();
// 根据id删除
//esBookRepository.deleteById(1L);
// 删除所有
//esBookRepository.deleteAll();
}
5. 查询
5.1 基本查询
方法 | 描述 |
---|---|
findAll() | 查询所有 |
findById() | 根据id查询 |
@Test
public void test4(){
//查询所有
Iterable<ESBook> iterable = esBookRepository.findAll();
Iterator<ESBook> iterator = iterable.iterator();
while (iterator.hasNext()){
ESBook esBook = iterator.next();
System.out.println(esBook);
}
}
@Test
public void test5(){
//根据id查询
Optional<ESBook> optional = esBookRepository.findById(1L);
ESBook esBook = optional.get();
System.out.println(esBook);
}
5.2 自定义方法
-
Spring Data 根据约定的方法名进行自动查询
- 要求: findBy字段 | 关键字
-
实例:
package com.czxy.repository; import com.czxy.vo.ESBook; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; /** * @Author Pole丶逐 * @Date 2020/4/13 21:15 * @E-mail */ public interface ESBookRepository extends ElasticsearchRepository<ESBook,Long> { //根据title查询 List<ESBook> findByTitle(String title); //根据price查询区间 List<ESBook> findByPriceBetween(Double start, Double end); //查询大于等于price List<ESBook> findByPriceGreaterThanEqual(Double price); }
5.3 自定义查询
5.3.1 关键字查询: match
-
查询条件构造器: NativeSearchQueryBuilder
-
查询: queryBuilder.withQuery( ... )
-
match条件: QueryBuilders.matchQuery("字段","值")
-
查询: esBookRepository.search( 条件 )
-
返回值: Page,容器,可以直接遍历获取数据
package com.czxy.test; import com.czxy.TestApplication; import com.czxy.repository.ESBookRepository; import com.czxy.vo.ESBook; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; /** * @Author Pole丶逐 * @Date 2020/4/14 15:55 * @E-mail */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestData { @Resource private ESBookRepository esBookRepository; @Test public void test1(){ //创建条件构造器器 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); //把条件查询match放到查询条件中 queryBuilder.withQuery(QueryBuilders.matchQuery("title","简史")); //创建构造对象并查询 Page<ESBook> page = esBookRepository.search(queryBuilder.build()); System.out.println("总条数: " + page.getTotalElements()); System.out.println("总页数: " + page.getTotalPages()); for (ESBook esBook : page) { System.out.println(esBook); } } }
5.3.2 多条件查询: bool -- must/mustNot(交集)
-
多条件拼凑: BoolQueryBuilder对象
- QueryBuilders.boolQuery()
-
并集操作: must()/mustNot()
@Test public void test2(){ // 创建条件查询构建器 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); // 获得bool查询条件 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); // 拼接查询条件 boolQueryBuilder.must(QueryBuilders.matchQuery("title","简史")); boolQueryBuilder.mustNot(QueryBuilders.matchQuery("title","时间")); // 把条件放入查询条件中 queryBuilder.withQuery(boolQueryBuilder); // 构建对象并查询 Page<ESBook> page = esBookRepository.search(queryBuilder.build()); // 循环遍历 page.forEach( esBook -> { System.out.println(esBook); }); }
5.3.3 多条件查询: bool -- should (并集)
-
交集操作: boolQueryBuilder.should()
@Test public void test3(){ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.should(QueryBuilders.matchQuery("title","人类")); boolQueryBuilder.should(QueryBuilders.matchQuery("title","简史")); queryBuilder.withQuery(boolQueryBuilder); Page<ESBook> page = esBookRepository.search(queryBuilder.build()); page.forEach( esBook -> { System.out.println(esBook); }); }
5.3.4 精准查询: term
-
精准查询: QueryBuilders.termQuery( 字段,值 )
@Test public void test4(){ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withQuery(QueryBuilders.termQuery("title","简史")); Page<ESBook> page = esBookRepository.search(queryBuilder.build()); page.forEach(esBook -> { System.out.println(esBook); }); }
5.3.5 区间查询: range
-
区间查询: QueryBuilders.rangeQuery( 字段 )
- lt(): 小于
- lte(): 小于等于
- gt(): 大于
- gte(): 大于等于
@Test public void test5(){ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withQuery(QueryBuilders.rangeQuery("price").gte(35.5).lte(40.0)); Page<ESBook> page = esBookRepository.search(queryBuilder.build()); page.forEach(esBook -> { System.out.println(esBook); }); }
5.3.6 分页查询:
-
分页查询: queryBuilder.withPageable()
- 分页工具类: PageRequest.of(pageNum,pageSIze)
@Test public void test6(){ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withPageable(PageRequest.of(1,2)); Page<ESBook> page = esBookRepository.search(queryBuilder.build()); page.forEach(esBook -> { System.out.println(esBook); }); }
5.3.7 排序查询:
-
排序查询: queryBuilder.withSort()
- 排序工具类: SortBuilders.fieldSort(排序字段)
- 排序方式: order(SortOrder.DESC | SortOrder.ASC)
@Test public void test7(){ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC)); Page<ESBook> page = esBookRepository.search(queryBuilder.build()); page.forEach(esBook -> { System.out.println(esBook); }); }
6. 总结
- 查询条件构造器: NativeSearchQueryBuilder
- 查询条件: queryBuilder.withQuery()
- 分页条件: queryBuilder.withPageable()
- 排序条件: queryBuilder.withSort()
- 构造: build()
- 查询条件,通过工具类QueryBuilders 获得
- 关键字查询: matchQuery(字段,值)
- 多条件查询: boolQuery()
- 必须有: must()
- 必须没有; mustNot()
- 并集: should()
- 精准查询: termQuery(字段,值)
- 区间查询: rangeQuery(字段)
- 大于: gt()
- 大于等于: gte()
- 小于: lt()
- 小于等于: lte()
- 分页条件: 工具类PageRequest
- 设置分页参数: PageRequest.of(pageNum,pageSize)
- 排序字段,通过工具类SortBuilders
- 排序字段: SortBuilders.fieldSort("字段")
- 排序方式: order(SortOrder.DESC | SortOrder.ASC)
- 查询结果: Page对象
- 总条数: getTotalElements()
- 总页数: getTotalPages()
- 第几页: getNumber()
- 每页个数: getSize()
- 过得内容: getContent()
- Page 对象可以直接遍历
来源:oschina
链接:https://my.oschina.net/xma444/blog/3234905