Springdata Elasticsearch的使用
1、创建一个springboot项目
添加如下依赖
依赖如下:
<?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>
<groupId>com.chaoxing</groupId>
<artifactId>springdataes-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springdataes-demo</name>
<description>springdataes-demo</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.example.springdataes_demo.SpringdataesDemoApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2 创建索引工具类pojo.Goods
3编写索引工具类
代码如下:
package com.example.springdataes_demo.pojo;
import lombok.Data;
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;
import java.math.BigDecimal;
/**
* 索引名,分片数,副本数,是否创建索引
* @Author :Kun
* @Date 2022/6/29 15:05
*/
@Document(indexName = "shop1",shards = 5,replicas = 1,createIndex = false)
@Data
public class Goods {
/***
* 商品ID
*
*/
@Id
private Integer goodsId;
/**
* 商品名称
*/
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String goodsName;
/**
* 市场价
*/
@Field(type = FieldType.Double)
private BigDecimal marketPrice;
/**
* 商品上传原始图
*/
@Field(type = FieldType.Keyword)
private String originalImg;
/**
* t_goods
*/
private static final long serialVersionUID = 1L;
}
4、 编写测试类测试功能是否实现
添加索引
代码如下:
package com.example.springdataes_demo;
import com.example.springdataes_demo.pojo.Goods;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.document.Document;
import java.util.Map;
@SpringBootTest
class SpringdataesDemoApplicationTests {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
public void testIndex(){
//获取索引对象
IndexOperations indexOperations= elasticsearchRestTemplate.indexOps(Goods.class);
//创建索引
indexOperations.create();
//获取映射
Document mapping = indexOperations.createMapping(Goods.class);
//将映射放进索引
indexOperations.putMapping(mapping);
//判断索引是否存在
boolean exists = indexOperations.exists();
System.out.println(exists);
//删除索引
//indexOperations.delete();
}
}
代码中即为映射设置的索引工具类
并创建索引
判断索引是否存在并输出
结果如下
控制台结果:
成功创建
head中:
成功创建对应的索引
删除索引
代码如下
@Test
public void testIndex(){
//获取索引对象
IndexOperations indexOperations= elasticsearchRestTemplate.indexOps(Goods.class);
indexOperations.delete();
//判断索引是否存在
boolean exists = indexOperations.exists();
System.out.println(exists);
}
结果显示:
控制台:
head:
删除成功
5、 操作自动生成索引并添加内容
1、设置操作的实体类createIndex=true
2、建立接口
package com.example.springdataes_demo.Dao;
import com.example.springdataes_demo.pojo.Goods;
import org.elasticsearch.client.ElasticsearchClient;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
/**
* @Author :Kun
* @Date 2022/6/29 16:19
*/
public interface GoodsRepository extends ElasticsearchRepository<Goods,Integer> {
}
3、方法引用
/**
* 通过Repository操作document
*/
@Test
public void testRepository(){
List<Goods> list = new ArrayList<>();
list.add(new Goods(150,"测试手机1",new BigDecimal("200"),"png"));
list.add(new Goods(151,"测试手机2",new BigDecimal("500"),"png"));
goodsRepository.saveAll(list);
}
4、结果显示
控制台:
head:
添加索引成功且成功添加数据
6、按名称进行查询
1、在接口中定义方法
/**
* 根据商品名称查询商品
* @param goodsName
* @return
*/
List<Goods> findByGoodsName(String goodsName);
2、测试使用
List<Goods> goodsList = goodsRepository.findByGoodsName("%测试%");
goodsList.forEach(System.out::println);
结果如下:
7、自己写查询语句通过id查询数据
1、在接口中添加方法
/**
* 根据ID查询商品
* 自己写查询语句
* @param id
* @return
*/
@Query("{\"match\":{\"goodsId\":{\"query\":\"?0\"}}}")
Goods findByIdValue(Integer id);
2、方法使用
3、结果
难点:es查询语句需要熟练掌握
8、使用elasticsearchRestTemplate进行增删改查
添加//更新
代码如下:
/**
* 增删改
*/
@Test
public void testCUD(){
List<Goods> list = new ArrayList<>();
//更新//添加(id存在就是更新,id不存在就是添加)
list.add(new Goods(150,"测试手机3",new BigDecimal("200"),"png"));
list.add(new Goods(153,"测试手机6",new BigDecimal("500"),"png"));
elasticsearchRestTemplate.save(list);
}
结果:
运行前结果:
运行后结果
更新成功
删除
结果显示
删除前
删除后
删除成功
9、匹配查询
代码如下:
/**
* 查询
*/
@Test
public void testSearch(){
NativeSearchQuery query= new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
.build();
SearchHits<Goods> searchHit = elasticsearchRestTemplate.search(query,Goods.class);
searchHit.forEach(System.out::println);
}
结果如下
10、删除查询出来的结果
代码如下:
elasticsearchRestTemplate.delete( new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
.build(),Goods.class,IndexCoordinates.of("shop1"));
查询的结果如下:
es数据库内容如下
运行结果如下
删除成功
11、高级操作 分页查询,排序,高量
分页查询
代码:
/**
* 高级查询 分页,高亮,排序
*/
@Test
public void testSearchHigh(){
NativeSearchQuery query= new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
//分页
.withPageable(PageRequest.of(0,5))
.build();
SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(query,Goods.class);
for(SearchHit<Goods> searchHit :searchHits){
float score = searchHit.getScore();
String id = searchHit.getId();
Goods goods =searchHit.getContent();
System.out.println("score:"+score);
System.out.println("id:"+id);
System.out.println("goods: " +goods);
System.out.println("=====================");
}
}
结果:
分数正序查询
代码:
package com.example.springdataes_demo;
import com.example.springdataes_demo.Dao.GoodsRepository;
import com.example.springdataes_demo.pojo.Goods;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
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 java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@SpringBootTest
class SpringdataesDemoApplicationTests {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
private GoodsRepository goodsRepository;
/**
* 操作索引
*/
@Test
public void testIndex(){
//获取索引对象
// IndexOperations indexOperations= elasticsearchRestTemplate.indexOps(Goods.class);
// //创建索引
// indexOperations.create();
// //获取映射
// Document mapping = indexOperations.createMapping(Goods.class);
// //将映射放进索引
// indexOperations.putMapping(mapping);
// //判断索引是否存在
// boolean exists = indexOperations.exists();
// System.out.println(exists);
//删除索引
// indexOperations.delete();
// //判断索引是否存在
// boolean exists = indexOperations.exists();
// System.out.println(exists);
}
/**
* 通过Repository操作document
*/
@Test
public void testRepository(){
//添加
List<Goods> list = new ArrayList<>();
list.add(new Goods(150,"测试手机1",new BigDecimal("100"),"png"));
list.add(new Goods(151,"测试手机2",new BigDecimal("200"),"png"));
list.add(new Goods(152,"测试手机3",new BigDecimal("300"),"png"));
list.add(new Goods(153,"测试手机4",new BigDecimal("400"),"png"));
list.add(new Goods(154,"测试手机5",new BigDecimal("500"),"png"));
list.add(new Goods(155,"测试手机6",new BigDecimal("600"),"png"));
list.add(new Goods(156,"测试手机7",new BigDecimal("700"),"png"));
list.add(new Goods(157,"测试手机8",new BigDecimal("800"),"png"));
list.add(new Goods(158,"测试手机9",new BigDecimal("900"),"png"));
list.add(new Goods(159,"测试手机10",new BigDecimal("1000"),"png"));
goodsRepository.saveAll(list);
//根据商品数查询
// List<Goods> goodsList = goodsRepository.findByGoodsName("%测试%");
// goodsList.forEach(System.out::println);
// Goods goods = goodsRepository.findByIdValue(150);
//System.out.println(goods);
}
/**
* 增删改
*/
@Test
public void testCUD(){
// List<Goods> list = new ArrayList<>();
// //更新//添加(id存在就是更新,id不存在就是添加)
// list.add(new Goods(150,"测试手机3",new BigDecimal("200"),"png"));
// list.add(new Goods(153,"测试手机6",new BigDecimal("500"),"png"));
// elasticsearchRestTemplate.save(list);
//删除
// elasticsearchRestTemplate.delete("151", IndexCoordinates.of("shop1"));
//删除查询出来的机构
elasticsearchRestTemplate.delete( new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
.build(),Goods.class,IndexCoordinates.of("shop1"));
}
/**
* 查询
*/
@Test
public void testSearch(){
NativeSearchQuery query= new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
.build();
SearchHits<Goods> searchHit = elasticsearchRestTemplate.search(query,Goods.class);
searchHit.forEach(System.out::println);
}
/**
* 高级查询 分页,高亮,排序
*/
@Test
public void testSearchHigh(){
NativeSearchQuery query= new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
//分页
.withPageable(PageRequest.of(0,5))
//排序分数正序排序
.withSort(SortBuilders.scoreSort().order(SortOrder.ASC))
.build();
SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(query,Goods.class);
for(SearchHit<Goods> searchHit :searchHits){
float score = searchHit.getScore();
String id = searchHit.getId();
Goods goods =searchHit.getContent();
List<Object>list = searchHit.getSortValues();
list.forEach(System.out::println);
System.out.println("score:"+score);
System.out.println("id:"+id);
System.out.println("goods: " +goods);
System.out.println("=====================");
}
}
}
结果如下
按名称正序查询
设置分页加排序方法一起
12、设置高亮获取高亮
设置默认高亮
运行结果
自己设置设置高亮
代码如下:
结果如下:
13、整个代码
package com.example.springdataes_demo;
import com.example.springdataes_demo.Dao.GoodsRepository;
import com.example.springdataes_demo.pojo.Goods;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
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 java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@SpringBootTest
class SpringdataesDemoApplicationTests {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
private GoodsRepository goodsRepository;
/**
* 操作索引
*/
@Test
public void testIndex(){
//获取索引对象
// IndexOperations indexOperations= elasticsearchRestTemplate.indexOps(Goods.class);
// //创建索引
// indexOperations.create();
// //获取映射
// Document mapping = indexOperations.createMapping(Goods.class);
// //将映射放进索引
// indexOperations.putMapping(mapping);
// //判断索引是否存在
// boolean exists = indexOperations.exists();
// System.out.println(exists);
//删除索引
// indexOperations.delete();
// //判断索引是否存在
// boolean exists = indexOperations.exists();
// System.out.println(exists);
}
/**
* 通过Repository操作document
*/
@Test
public void testRepository(){
//添加
List<Goods> list = new ArrayList<>();
list.add(new Goods(150,"测试手机1",new BigDecimal("100"),"png"));
list.add(new Goods(151,"测试手机2",new BigDecimal("200"),"png"));
list.add(new Goods(152,"测试手机3",new BigDecimal("300"),"png"));
list.add(new Goods(153,"测试手机4",new BigDecimal("400"),"png"));
list.add(new Goods(154,"测试手机5",new BigDecimal("500"),"png"));
list.add(new Goods(155,"测试手机6",new BigDecimal("600"),"png"));
list.add(new Goods(156,"测试手机7",new BigDecimal("700"),"png"));
list.add(new Goods(157,"测试手机8",new BigDecimal("800"),"png"));
list.add(new Goods(158,"测试手机9",new BigDecimal("900"),"png"));
list.add(new Goods(159,"测试手机10",new BigDecimal("1000"),"png"));
goodsRepository.saveAll(list);
//根据商品数查询
// List<Goods> goodsList = goodsRepository.findByGoodsName("%测试%");
// goodsList.forEach(System.out::println);
// Goods goods = goodsRepository.findByIdValue(150);
//System.out.println(goods);
}
/**
* 增删改
*/
@Test
public void testCUD(){
// List<Goods> list = new ArrayList<>();
// //更新//添加(id存在就是更新,id不存在就是添加)
// list.add(new Goods(150,"测试手机3",new BigDecimal("200"),"png"));
// list.add(new Goods(153,"测试手机6",new BigDecimal("500"),"png"));
// elasticsearchRestTemplate.save(list);
//删除
// elasticsearchRestTemplate.delete("151", IndexCoordinates.of("shop1"));
//删除查询出来的机构
elasticsearchRestTemplate.delete( new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
.build(),Goods.class,IndexCoordinates.of("shop1"));
}
/**
* 查询
*/
@Test
public void testSearch(){
NativeSearchQuery query= new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
.build();
SearchHits<Goods> searchHit = elasticsearchRestTemplate.search(query,Goods.class);
searchHit.forEach(System.out::println);
}
/**
* 高级查询 分页,高亮,排序
*/
@Test
public void testSearchHigh(){
NativeSearchQuery query= new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("goodsName","测试"))
//分页+排序
.withPageable(PageRequest.of(0,5, Sort.Direction.DESC,"goodsId"))
//排序分数正序排序
//.withSort(SortBuilders.scoreSort().order(SortOrder.ASC))
//按照ID正序排序
// .withSort(SortBuilders.fieldSort("goodsId").order(SortOrder.ASC))
//高亮,默认<em>测试</em> em为斜体
//.withHighlightFields(new HighlightBuilder.Field("goodsName"))
//设置高亮
.withHighlightBuilder(new HighlightBuilder().field("goodsName")
.preTags("<span style='color:red'>").postTags("<span>"))
.build();
SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(query,Goods.class);
for(SearchHit<Goods> searchHit :searchHits){
float score = searchHit.getScore();
String id = searchHit.getId();
Goods goods =searchHit.getContent();
List<Object>list = searchHit.getSortValues();
String goodsName = searchHit.getHighlightField("goodsName").get(0);
list.forEach(System.out::println);
System.out.println("score:"+score);
System.out.println("id:"+id);
System.out.println("goods: " +goods);
System.out.println("goodsName高亮:"+goodsName);
System.out.println("=====================");
}
}
}