一、检索
1、解释
- 我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;
2、ElasticSearch简介
- Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用 多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github 等大型的站点也是采用了ElasticSearch作为其搜索服务,
二、概念
1、解释
- 以员工文档的形式存储为例:一个文档代表一个员工数据。存储数据到 ElasticSearch 的行为叫做索引,但在索引一个文档之前,需要确定将文档存储在哪里
- 一个 ElasticSearch 集群可以 包含多个索引,相应的每个索引可以包含多个类型 。 这些不同的类型存储着多个文档 ,每个文档又有多个属性
- 类似关系
- 索引-数据库
- 类型-表
- 文档-表中记录
- 属性-列
2、SpringBoot默认支持两种技术来和ES交互
-
Jest(默认不生效)
需要导入jest的工具包(io.searchbox.client.JestClient)才生效
-
SpringData ElasticSearch【ES版本有可能不合适】
版本适配说明:https://github.com/spring-projects/spring-data-elasticsearch
如果版本不适配
- 升级SpringBoot版本
- 安装对应版本的ES
- Client 节点信息clusterNodes;clusterName等属性
- ElasticsearchTemplate 操作es
- 编写一个 ElasticsearchRepository 的子接口来操作ES
两种用法:https://github.com/spring-projects/spring-data-elasticsearch
三、用Jest操作ES
1、新建一个SpringBoot项目
- 引入spring-boot-starter-data-elasticsearch
- 勾选:Spring Web、Spring Data Elasticsearch
3、添加Jest依赖
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>5.3.3</version>
</dependency>
4、配置application.yml文件
spring:
elasticsearch:
jest:
uris: http://192.168.241.135:9200
5、新建一个entity类
import io.searchbox.annotations.JestId;
public class Article {
@JestId
private Integer id;
private String author;
private String title;
private String content;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
6、测试
@Autowired
private JestClient jestClient;
@Test
void contextLoads() {
//1、给ES中索引(保存)一个文档
Article article = new Article();
article.setId(1);
article.setAuthor("张三");
article.setTitle("好消息");
article.setContent("你好,降价了");
//Builder(保存内容)
//index(索引位置)
//type(类型)
//build():构建
//构建一个索引功能
Index index = new Index.Builder(article).index("itan").type("news").build();
try {
//执行
jestClient.execute(index);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void search(){
//查询表达式
String json="{\n"+
"\"query\":{\n"+
"\"match\":{\n"+
"\"content\":\"你好\"\n"+
"}\n"+
"}\n"+
"}";
//构建搜索
Search build = new Search.Builder(json).addIndex("itan").addType("news").build();
try {
//执行
SearchResult result = jestClient.execute(build);
System.out.println(result.getJsonString());
} catch (IOException e) {
e.printStackTrace();
}
}
7、查询是否成功:ip:9200/索引名/类型/id
8、其他操作索引,请查看官方文档
9、注意:
- ** 同一个index下不能有两个type **
四、用SpringData ElasticSearch操作ES
1)、编写一个ElasticsearchRepository的子接口来操作ES
1、打开注释掉的org.springframework.boot
2、配置application.yml文件
spring:
data:
elasticsearch:
#配置ip和端口
cluster-nodes: 192.168.241.135:9300
cluster-name: docker-cluster
repositories:
enabled: true
3、编写一个实体类
/**
* indexName:索引的名字
* type:类型
*/
@Document(indexName = "itan",type = "book")
public class Book implements Serializable {
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Id
private Integer id;
@JsonProperty
private String bookName;
@JsonProperty
private String author;
public Book(Integer id, String bookName, String author) {
this.id = id;
this.bookName = bookName;
this.author = author;
}
public Book() {
}
@Override
public String toString() {
return "Book{" +
"id='" + id + '\'' +
", bookName='" + bookName + '\'' +
", author='" + author + '\'' +
'}';
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
4、编写一个类BookRepository继承ElasticsearchRepository
import com.itan.elastic.entity.Book;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public interface BookRepository extends ElasticsearchRepository<Book,Integer>{
//自定义方法
public List<Book> findBookByBookNameLike(String bookName);
}
5、测试
/**
* 保存一个索引
*/
@Autowired
private BookRepository bookRepository;
@Test
public void test01(){
Book book=new Book(3,"红楼梦","小雪");
this.bookRepository.save(book);
}
/**
* 使用自定义的方法查询
*/
@Test
public void test02(){
List<Book> list = this.bookRepository.findBookByBookNameLike("红");
for (Book book:list){
System.out.println(book);
}
}
6、注意:
- 同一个index(索引名)下不能有两个type
- 自定义的查询方法名有特殊规定,不然会报错
2)、ElasticsearchTemplate 操作es
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
/**
* 添加
*/
@Test
public void test3() {
Book book = new Book(5,"你好世界","安然");
IndexQuery indexQuery = new IndexQueryBuilder().withObject(book).withIndexName("itan").withType("book").build();
this.elasticsearchTemplate.index(indexQuery);
}
/**
* 查询
*/
@Test
public void test2() {
Client client = elasticsearchTemplate.getClient();
GetResponse response = client.prepareGet("itan", "book", "1").get();
System.out.println(response.getSource());
}