总结
我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch(Spring Data的子项目)为我们提供了非常便捷的检索功能支持。
ElasticSearch是一个分布式搜索服务,提供Restful API,底层基于Lucene(开源的搜索引擎软件工具包,我们需要自己写代码调用里面的api,而es对其做了封装。提供了restful api操作接口,通过发送请求的方式应用起来),采用多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github等大型的站点也是采用了ElasticSearch作为其搜索服务。
Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:
一个分布式的实时文档存储,每个字段 可以被索引与搜索
一个分布式实时分析搜索引擎
能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据
ElasticSearch官网地址:https://www.elastic.co/。
ES使用Java写的,启动默认会使用2G的堆内存空间。
ES 是面向文档的,意味着它存储整个对象或者文档。ES不仅存储文档,而且索引每个文档的内容可以被检索。在ES中,你对文档进行索引、检索、排序和过滤。而不是对行列数据。这是一种完全你不同的思考数据的方式。也是ES能支持复杂全文检索的原因。
一个对象放到ES中,最终会转成JSON格式进行存储。 JSON支持跨平台,轻量级。
索引--其实就存储的意思: 数据存储到ES的行为叫做索引(动词),但是索引在一个文档之前,需要确定将文档存储在哪里
在ES里面有多个索引(名词),每个索引包含多个类型,每个类型包含多个文档,每个文档有多个属性
做个类比吧:
和MySQL的类比关系
ES集群相当于我们连接上MySQL数据库
然后往哪个数据库查询东西(MySQL里面很多数据库) 对应索引
数据库里面有很多找张表 对应表
表里面有一行一行的记录 对应文档
表里面的列 每一列都对应字段
一:存储数据
如果给tx的员存储数据,4步操作
每个员工索引一个文档,包括该员工的所有信息
每个文档都将是employee类型
该类型位于tianxiao索引内
该索引保存在ES集群中
一个访问搞定~ PUT 请求+ JSON数据
索引名字/类型名字/数据的特定标识(1号数据)
PUT /tianxaio/employee/1
{
"name" : "Jack",
"age" : "24",
"motto" : "996 是福分"
}
put两次版本字段进行叠加: 相当于update
注意:
put 可以新增和修改文档
二:检索数据
GET请求 索引/类型/一号数据
GET /tianxaio/employee/1
注意搜索所有的员工:
GET /tianxaio/employee/_search
按照条件去查找:
GET /tianxaio/employee/_search?q=name:Jack
如果使用查询表达式:
请求体里面放入这一坨数据
GET /tianxaio/employee/_search
{
"query" :{
"match" : {
"name" : "Jack"
}
}
}
语法就是: 查询 规则就是匹配name为Jack的数据 (注意对于POST man 这里虽然理论上是GET请求,但是这一坨数据是放在请求体里面的,GET是不合适的,所以就放入了POST请求体了)
JSON复杂,那么ES查询操作就可以更复杂了,JSON形式的查询表达式示相当重要的
GET /tianxaio/employee/_search
{
"query": {
"bool": {
"must":
{
"match": {
"name" : "Jack"
}
},
"filter": {
"range": {
"age": { "gt": 11 }
}
}
}
}
}
大于11岁的
全文检索:
根据每一个员工的motto 字段来查 ,只要这个字段包换我们要检索的字段就会被检索到
GET /tianxaio/employee/_search
{
"query": {
"match": {
"motto": "996"
}
}
}
结果:
做了一个like操作 996 和 福气 包含的都被查询出来了
如果是作为一个指定的完整的单词去查询呢?
GET /tianxaio/employee/_search
{
"query": {
"match_phrase": {
"motto": "996"
}
}
}
结果:
三:删除数据
DELETE
DELETE /tianxaio/employee/1
使用rest风格的api直接操作就可以了
Spring Boot 整合ES
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
Spring Boot默认用Spring Data 项目下的ElasticSearch模块进行操作
SpringBoot 默认支持两种技术和ES交互
1、 Jest (默认不生效的)
2、 SpringData ElasticSearch :
帮助提供了一个客户端
配置了ElasticSearchTemplate. Spring Boot 整合其他组件一如既往的Template套路
编写ElasticsearchRepository的子接口来操作es (类似JPA的编程方式)
yml的配置参考:
yml:
spring.data.elasticsearch.cluster-name=myes
spring.data.elasticsearch.cluster-nodes=192.168.91.7:9300
Bean:
//一定要是有get方法啊啊啊 我玩儿时候 没有get方法 竟然在es中可以查到数据 但是差不多具体的信息内容!!没有属性值!!
@Document(indexName = "test_es",type = "book") //book作为文档存在那个索引 哪个类下面
public class MyBook {
private Integer id;
private String bookName;
private String author;
public MyBook() {
}
public MyBook(Integer id, String bookName, String author) {
this.id = id;
this.bookName = bookName;
this.author = author;
}
public Integer getId() {
return id;
}
public String getBookName() {
return bookName;
}
public String getAuthor() {
return author;
}
public void setId(Integer id) {
this.id = id;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return super.toString();
}
}
Dao
public interface BookRepository extends ElasticsearchRepository<MyBook, Integer> { //book的主鍵是Interger的
}
启动类:
@SpringBootApplication
public class ElasticsearchApplication {
public static void main(String[] args) {
SpringApplication.run(ElasticsearchApplication.class, args);
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticsearchApplicationTests {
@Resource
BookRepository bookRepository;
@Test
public void test01(){
MyBook myBook = new MyBook();
myBook.setId(1);
myBook.setAuthor("toov5");
myBook.setBookName("新的测试");
System.out.println(myBook.getBookName());
bookRepository.index(myBook);
}
@Test
public void contextLoads() {
}
}
查询:
GET /test_es/book/1
结果:
也可以自定义方法!
对于基本的增删改查 ElasticsearchRepository<MyBook, Integer> 都包含了
CTRL + F12 选中菜单栏 可以查看原先自带的方法
我们可以自定义其他的使用方法!
Dao:
public interface BookRepository extends ElasticsearchRepository<MyBook, Integer> { //book的主鍵是Interger的
public List<MyBook> findMyBookByBookNameLike(String bookName); //by后面的BookName与bean对应哦
}
测试:
@Test
public void test01(){
List<MyBook> MyBook = bookRepository.findMyBookByBookNameLike("编程");
MyBook.forEach(
b->{
System.out.println(b.getBookName());
}
);
}
结果:
查询的命名方法,可以详情查看Spring Data官方文档!
https://docs.spring.io/spring-data/elasticsearch/docs/3.0.6.RELEASE/reference/html/
大家可以点进去看看