SpringBoot自学好几天 中途开始写笔记 SpringBoot与检索 ElasticSearch - jest 整合 20190302
一、检索
我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;
Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github等大型的站点也是采用了ElasticSearch作为其搜索服务,
- 安装
[[email protected] ~]# docker pull registry.docker-cn.com/library/elasticsearch
- 启动
docker默认占用2G内存 但是安装的虚拟机没有那么大 所以呢用 -e 限制堆内存
默认web通信是9200 分布式的情况下elasticsearch各个节点之间通信是9300
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name ES01 5acf0e8da90b
docker ps
- 测试 浏览器输入:http://192.168.2.118:9200/
- 简单使用 https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
索引就相当于mysql的数据库
类型就是mysql的表
文档就是mysql的一条记录
属性就是mysql的列
#megacorp 索引名称
#employee 类型名称
#1 特定id
#json格式内容就是文档
#json中每一个属性就是属性
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
用postman发送请求:
响应:
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}
依次保存多条数据:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_indexing_employee_documents.html
- 搜索数据
如果把这里的get请求换成delete就会删除指定员工信息
如果把这里的get换成head 就是查询有没有信息 有的话状态码是200 没有的话状态码是404
{
"took": 83,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "megacorp",
"_type": "employee",
"_id": "2",
"_score": 1,
"_source": {
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [
"sports",
"music"
]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "3",
"_score": 1,
"_source": {
"first_name": "Douglas",
"last_name": "Fir",
"age": 35,
"about": "I like to build cabinets",
"interests": [
"forestry"
]
}
}
]
}
}
- 其他
根据条件过滤:
根据last_name过滤
http://192.168.2.118:9200/megacorp/employee/_search?q=last_name:Smith
根据查询表达式搜索:
更多:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_more_complicated_searches.html
这里只是跟springboot简单的结合 不设计到深入了解 不过这个很高级啊 以后有时间要看看 分布式搜索什么的
二、创建新工程 进行测试
- pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<!--说是后来版本改成了 直接引用这个 -->
<artifactId>spring-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
-
SpringBoot 默认支持2中技术与ES交互
1). Jest
org.springframework.boot.autoconfigure.elasticsearch.jest
默认不生效的,需要导入Jest工具包io.searchbox.client.JestClient
2). SpringData ElasticSearch
org.springframework.boot.autoconfigure.data.elasticsearch -
ElasticsearchAutoConfiguration
1)jestClient节点信息 给了一个客户端 需要制定clusterName clusterNodes -
ElasticsearchDataAutoConfiguration
1)ElasticsearchTemplate 操作ES -
ElasticsearchRepositoriesAutoConfiguration
作用就是启用了ElasticsearchRepository
类似于jpa编程方式 我们继承ElasticsearchRepository 就会有相应的方法
@NoRepositoryBean
public interface ElasticsearchRepository<T, ID extends Serializable> extends ElasticsearchCrudRepository<T, ID> {
<S extends T> S index(S var1);
Iterable<T> search(QueryBuilder var1);
Page<T> search(QueryBuilder var1, Pageable var2);
Page<T> search(SearchQuery var1);
Page<T> searchSimilar(T var1, String[] var2, Pageable var3);
void refresh();
Class<T> getEntityClass();
}
- 测试Jest
先把spring-data-elasticsearch 注释掉
导入Jest
<!-- <dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
</dependency>-->
<!-- https://mvnrepository.com/artifact/io.searchbox/jest -->
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<!--依赖6版本有问题 改成了5版本-->
<version>5.3.4</version>
</dependency>
创建实体类:
/**
* @author LM
* @create 2019-03-02 21:03
*/
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;
}
}
存入数据:
@Autowired
JestClient jestClient;
@Test
public void contextLoads() throws IOException {
//1. 给Es中保存一个文档
Article article = new Article();
article.setId(1);
article.setTitle("标题");
article.setAuthor("我啊");
article.setContent("十多号if了解到肺结核覅皇帝发货单");
//构建一个索引功能 索引:suoyin 分类:news id:1 article里边有了 如果没有可以直接调用.id() 指定
Index build = new Index.Builder(article).index("suoyin").type("news").build();
jestClient.execute(build);
}
搜索数据:
@Test
public void search() throws IOException {
//查询表达式
String json = "\n" +
"{\n" +
" \"query\" : {\n" +
" \"match\" : {\n" +
" \"content\" : \"订单\"\n" +
" }\n" +
" }\n" +
"}";
Search build = new Search.Builder(json).addIndex("suoyin").addType("news").build();
//搜索
SearchResult execute = jestClient.execute(build);
//打印
System.out.println(execute.getJsonString());
}
结果: