目录
🍺二、SpringBoot 项目整合 Elasticsearch
🍸前言
上次了解了 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
实体类字段中涉及到的几个注解如下,类中包含的字段和创建的索引库字段对应即可:
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 ,为了方便操作以及定制化方法,可以自己定义一个接口继承,代码如下:
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 业务接口方法定义
业务方法主要是定义一些常用的操作方法,方便调用,本地创建了几个常用的方法如下:
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 业务方法逻辑实现
就是业务层接口的方法实现
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 编写测试类
测试几个主要的方法结果
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 高亮查询方法测试
结果可以看到查出来的结果由我们自定义的前后标签包裹,页面上显示的时候也就有高亮显示的效果了
🍷四、章末
文章到这里就结束了~