ES的简单使用 SpringBoot整合ES(Jest, spring-data-elasticsearch)
检索功能
- 简介
- 我们的应用经常需要添加检索功能, 开源的ElasticSearch是目前全文搜索引擎的首选. 他可以快速存储, 搜索, 和分析海量数据, SpringBoot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持.
- Elasticsearch是一个分布式搜索服务, 提供Restful API, 底层基于Lucene, 采用多shard(分片)的方式保证数据安全, 并且提供自动resharding的功能, github等大型的站点也是采用了ElasticSearch作为其搜索服务.
- 安装Elasticsearcch
- 以docker的方式
docker pull elasticsearch:7.7.1
docker run -d -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" --name es01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" 镜像ID
- 简单使用
- ES是面向文档的, 意味着它存储整个对象或文档, 同时, 索引每个文档的内容使之可以被检索.
- 在ES中, 使用JSON作为文档的序列化格式.
- 如一个User对象
- 简单操作
- 存储雇员数据, 以雇员文档的形式存储, 存储数据到ES的行为叫做索引. 但在索引一个文档之前, 需要确定将文档存储到哪.
- ES集群中可以有多个索引, 每个索引可包含多个类型, 每个类型可包含多个文档, 而每个文档之间又可以有多个属性.
- 对于雇员目录, 做如下操作
- 每个雇员索引一个文档, 包含该雇员的所有信息.
- 每个文档都是employee类型
- 该类型位于索引megacors内.
- 该索引保存在我们的ES集群中
PUT /megacorp/employee/1
{
"first_name" : "john",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests" : ["sports", "music"]
}
megacorp是索引名称
employee是类型名称
1代表特定雇员的ID
- 检索时只需发GET /megacorp/employee/1
- 同理, 发DELETE请求是删除, 发HEAD请求来检查是不是有这个员工
- 若要更新已存在的文档, 只需再次PUT.
- 这里的版本会叠加, 同时result : "updated"
- 搜索功能
- 查询所有员工
GET /megacorp/employee/_search
- 按条件查找
GET /megacorp/employee/_search?q=last_name:Smith
- 查询表达式
- 全文检索
- ES中的检索并非像传统数据库那样内容必须严格一致才能搜出来, 而有一个字段叫相关性得分, 得分越高, 则字段越相近.
- 短语搜索(严格匹配)
- 需用到"match_phrase"
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
- 高亮搜索
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight" : {
"fields" : {
"about" : {}
}
}
}
SpringBoot整合ElasticSearch
- 依赖
- 导入依赖
- SpringBoot默认支持两种技术与ES交互
<!--SpringBoot默认使用SpringData ElasticSearch模块进行操作-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
或者
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>6.3.1</version>
</dependency>
- Jest
- 不导入第二个依赖不会生效.
- SpringData ElasticSearch
- Client 节点信息(clusterNodes, clusterName)
- ElasticsearchTemplate 操作ES
- 编写一个ElasticsearchRepository的子接口来操作ES
- 使用Jest操作ES
- 配置: application.properties
spring.elasticsearch.jest.uris=http://192.168.13.129:9200/
- 测试
- bean信息
public class Article {
@JestId //主键
private Integer id;
private String auth;
private String title;
private String content;
//...
}
- 测试
@Autowired
private JestClient jestClient;
//测试添加
@Test
public void contextLoads() {
//1. 给ES中索引一个文档
Article article = new Article();
article.setId(1);
article.setTitle("好消息");
article.setAuth("zhangsan");
article.setContent("Hello world");
//构建一个索引功能
Index index = new Index.Builder(article).index("yellowstreak").type("news").build();
try {
//执行
jestClient.execute(index);
} catch (IOException e) {
e.printStackTrace();
}
}
//测试搜索
@Test
public void search() {
//查询表达式
String json = "{\n" +
"\t\"query\" : {\n" +
"\t\t\"match\" : {\n" +
"\t\t\t\"content\" : \"hello\"\n" +
"\t\t}\n" +
"\t}\n" +
"}";
//构建搜索功能
Search search = new Search.Builder(json).addIndex("yellowstreak").addType("news").build();
//执行
try {
SearchResult result = jestClient.execute(search);
System.out.println(result.getJsonString());
} catch (IOException e) {
e.printStackTrace();
}
}
- 整合SpringData ES模块
- 注意: 目前spring-data-elasticsearch支持6.x版本, 不支持7.x版本.
- 版本不匹配会报错
NoNodeAvailableException None of the configured nodes are available
- 配置
spring.data.elasticsearch.cluster-name=docker-cluster
spring.data.elasticsearch.cluster-nodes=192.168.13.129:9300
- 用法
- bean
@Document(indexName = "yellowstreak", type = "book")
public class Book {
private Integer id;
private String bookName;
private String author;
//...
}
- 编写一个ElasticsearchRepository的子接口
public interface BookRepository extends ElasticsearchRepository<Book, Integer> {
//自定义命名方法名
public List<Book> finByBookNameLike(String bookName);
- 测试
@Autowired
private BookRepository bookRepository;
@Test
public void test02() {
Book book = new Book();
book.setId(1);
book.setBookName("西游记");
book.setAuthor("吴承恩");
bookRepository.index(book);
List<Book> books = bookRepository.finByBookNameLike("游");
}