目录
[🍻一、Elasticsearch 本地环境启动](#🍻一、Elasticsearch 本地环境启动)
[🍺二、SpringBoot 项目整合 Elasticsearch](#🍺二、SpringBoot 项目整合 Elasticsearch)
[2.1 引入 ES 依赖](#2.1 引入 ES 依赖)
[2.2 配置 ES 属性](#2.2 配置 ES 属性)
[2.3 创建实体类](#2.3 创建实体类)
[2.4 操作 ES 的工具类](#2.4 操作 ES 的工具类)
[2.5 操作 ES 的业务层](#2.5 操作 ES 的业务层)
[3.1 编写测试类](#3.1 编写测试类)
[3.2 接口测试](#3.2 接口测试)
🍸前言
上次了解了 Elasticsearch 中基本属性的使用以及高级查询的操作,操作过程中使用的是 ES 可视化操作工具,接下来看看在 SpringBoot 项目中如何使用 Java API 操作 ES ,原文链接如下:
【Elasticsearch<三>✈️✈️】常见基本属性的用法以及与MySQL的区别-CSDN博客
🍻一、Elasticsearch 本地环境启动
依次启动 ES 服务器,kinaba 应用,以及浏览器插件 ElasticSearch-head
准备好一个 SpringBoot 测试项目
🍺二、SpringBoot 项目整合 Elasticsearch
2.1 引入 ES 依赖
Springboot 推荐使用的 ES 对应的版本信息如下(不一定要严格按照版本对应):
本地使用的是 springboot 版本 2.7 ,所以 ES 版本选择的是 7.17 ,这样做的目的是尽量减少编译时由于版本间支持的内容差异引起的异常情况
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.17.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
2.2 配置 ES 属性
简单的属性只需配置下 ES 的服务器地址即可
application.properties 配置文件格式如下:
spring.elasticsearch.uris=http://127.0.0.1:9200
// .yml 文件对应的格式如下
spring:
elasticsearch:
uris: http://127.0.0.1:9200
2.3 创建实体类
注:这里的实体类指定了索引库,需要提前在 kibana 上操作创建对应的索引库,本地使用的是上篇文章中创建好的索引 testmapping
实体类字段中涉及到的几个注解如下,类中包含的字段和创建的索引库字段对应即可:
@Id
@Id 注解是Elasticsearch中用于标识文档唯一标识符(ID)的注解
@Field 用于定义字段的属性
(store = true)
: 是否将字段的原始值存储在文档中。如果设置为true,表示将该字段的原始值存在文档中(原始值指的是不会经过分词处理)analyzer = "ik_smart"
: 指定分析器(analyzer),这里使用了"ik_smart"分析器。index = true
: 是否对字段进行索引。如果设置为true,则可以在该字段上执行搜索操作;如果设置为false,则不能搜索该字段的内容。searchAnalyzer = "ik_smart"
: 指定搜索时使用的分析器。通常与analyzer
相同,但有时可能会使用不同的分析器来进行搜索。
java
import lombok.Data;
import nonapi.io.github.classgraph.json.Id;
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;
/**
* @author ben.huang
*/
@Data
//@Document 文档对象注解 (这里指定索引名称)
@Document(indexName = "testmapping")
public class Elasticsearch {
@Id
//@Field , 每个文档的字段配置(类型,是否分词,是否存储,分词器),只有text 类型的字段支持分词
@Field(store = true, index = false, type = FieldType.Text)
private String id;
@Field(store = true, analyzer = "ik_smart", index = true, searchAnalyzer = "ik_smart", type = FieldType.Text)
private String title;
@Field(store = true, index = true, type = FieldType.Double)
private Double price;
@Field(store = true, index = true, type = FieldType.Date)
private Date createTime;
@Field(store = true, analyzer = "ik_smart", index = true, searchAnalyzer = "ik_smart", type = FieldType.Text)
private String description;
@Field(index = true, analyzer = "ik_smart", store = true, searchAnalyzer = "ik_smart", type = FieldType.Text)
private String content;
}
2.4 操作 ES 的工具类
Java 可以通过 org.springframework.data.elasticsearch.repository.ElasticsearchRepository
类操作 ES ,为了方便操作以及定制化方法,可以自己定义一个接口继承,代码如下:
接口上的两个泛型参数表示操作
Elasticsearch
的实体,并且实体的主键类型是Integer
。这里自定义了一个高亮查询方法,使用了
@Highlight
注解,表示要对搜索结果进行高亮显示。在@Highlight
注解中,指定了要高亮显示的字段为title
,并且设置了一些高亮显示的参数,如前置标签、后置标签以及片段数等。方法接收字符串参数
title
,用于指定要搜索的标题。返回类型是List<SearchHit<Elasticsearch>>
,其中SearchHit
对象包含了搜索结果的详细信息,如匹配的文档、匹配度分数等。
java
import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.annotations.HighlightParameters;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface TestElasticsearchRepository extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository<Elasticsearch,Integer> {
@Highlight(
fields = {@HighlightField(name = "title")},
parameters = @HighlightParameters(preTags = {"<span style='color:red'>"}, postTags = {"</span>"}, numberOfFragments = 0)
)
List<SearchHit<Elasticsearch>> findByTitle(String title);
}
2.5 操作 ES 的业务层
2.5.1 业务接口方法定义
业务方法主要是定义一些常用的操作方法,方便调用,本地创建了几个常用的方法如下:
java
import org.springframework.data.elasticsearch.core.SearchHit;
import java.util.List;
/**
* @author ben.huang
*/
public interface ElasticSearchService {
//保存和修改
void save(Elasticsearch article);
//查询id
Elasticsearch findById(Integer id);
//删除指定ID数据
void deleteById(Integer id);
//查询索引库章的总共文档数
long count();
//是否存在指定的文档ID
boolean existsById(Integer id);
//高亮查询
List<SearchHit<Elasticsearch>> findByTitle(String title);
}
2.5.2 业务方法逻辑实现
就是业务层接口的方法实现
java
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author ben.huang
*/
@Service
public class ElasticSearchServiceImpl implements ElasticSearchService {
@Resource
private TestElasticsearchRepository elasticSearchRepository;
@Override
public void save(Elasticsearch elasticSearch) {
elasticSearchRepository.save(elasticSearch);
}
@Override
public Elasticsearch findById(Integer id) {
return elasticSearchRepository.findById(id).orElse(new Elasticsearch());
}
@Override
public void deleteById(Integer id) {
elasticSearchRepository.deleteById(id);
}
@Override
public long count() {
return elasticSearchRepository.count();
}
@Override
public boolean existsById(Integer id) {
return elasticSearchRepository.existsById(id);
}
@Override
public List<SearchHit<Elasticsearch>> findByTitle(String title) {
return elasticSearchRepository.findByTitle(title);
}
}
🍹三、接口测试
3.1 编写测试类
测试几个主要的方法结果
java
import com.hb.demo.DemoApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.List;
/**
* @author ben.huang
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class ESTest {
@Resource
private ElasticSearchService elasticSearchService;
/**
* 添加文档或者修改文档(以id为准)
*/
@Test
public void saveElasticSearch() {
Elasticsearch elasticSearch = new Elasticsearch();
elasticSearch.setId("5");
elasticSearch.setTitle("SpringBoot ElasticSearch Test");
elasticSearch.setDescription("SpringBoot 整合 ES 操作数据 SpringBoot ElasticSearch Test");
elasticSearchService.save(elasticSearch);
}
@Test
public void findById() {
Elasticsearch byId = elasticSearchService.findById(1);
System.out.println(byId);
}
@Test
public void deleteById() {
elasticSearchService.deleteById(4);
}
@Test
public void count() {
long count = elasticSearchService.count();
System.out.println(count);
}
@Test
public void existsById() {
boolean b = elasticSearchService.existsById(5);
System.out.println(b);
}
@Test
public void findByTitleOrContent() {
List<SearchHit<Elasticsearch>> byTitleOrContent = elasticSearchService.findByTitle("服饰类商品");
for (SearchHit<Elasticsearch> elasticSearchService : byTitleOrContent) {
String id = elasticSearchService.getId();
System.out.println(id);
List<String> title = elasticSearchService.getHighlightField("title");
System.out.println(title);
}
}
}
3.2 接口测试
3.2.1 保存文档方法测试
结果如下,文档正确插入到 ES 中并且可以在 插件上查询到
3.2.2 根据文档 id 查询方法测试
这里的测试结果是返回了一个空的 ES 对象,是因为方法的实现中指明了,如果未找到返回一个空的 Optinal 对象,如果 Optional 对象为空,则返回一个新创建的空的 Elasticsearch 对象,避免返回 null
3.2.3 索引库文档数量查询方法测试
查询出当前索引库(testmapping) 中有七条数据
3.2.4 是否存在对应的文档方法测试
3.2.5 高亮查询方法测试
结果可以看到查出来的结果由我们自定义的前后标签包裹,页面上显示的时候也就有高亮显示的效果了
🍷四、章末
文章到这里就结束了~