一、ElasticSearch 介绍

​ 开源的 ElasticSearch 是目前全文搜索引擎的首选,它是一个分布式搜索服务,提供Restful API,它可以快速地存储、搜索和分析海量数据。底层基于 Lucene,采用多 shard(分片)的方式保证数据安全,并且提供自动 resharding 的功能,github 等大型站点也是采用 ElasticSearch 作为其搜索服务。

​ ElasticSearch 是面向文档的,它存储整个对象(文档),它使用 JSON 作为文档的序列化格式。一个 ElasticSearch 集群可以包含多个索引,相应的每个索引可以包含多个类型。这些不同的类型存储着多个文档,每个文档又有多个属性。

二、ElasticSearch 快速入门

1、dokcer 安装 ElasticSearch

dokcer pull elasticsearch:6.4.3 # 获取镜像 注意:如果后面整合 spring boot 的话,就要与 spring boot 的版本相对应,我后面创建的 spring boot 项目是 2.1.2 对应的 spring-data-elasticsearch 是 3.1.4,详情参考 springboot 官方:https://github.com/spring-projects/spring-data-elasticsearch 里面的对照表,版本不对应的话,后面用 spring data 使用 ES 的话可能会有问题。
[root@izwz9d74k4cznxtxjeeur9z ~]# docker run -d --name=ES -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms1024M -Xmx1024m" elasticsearch:6.4.3
# 第一个端口是web通信端口,第二个端口是节点通信端口,设置为了单节点模式并规定了运行时最小堆内存为1024M,最大堆内存为1024M(默认情况下,要占将近2个G) 

输入 http://服务器地址:9200/,返回 JSON ,运行成功。

2、练习

使用软件 Postman 模拟发送 Restful 请求,练习参考官方文档。

  • 索引雇员文档:第一个业务需求就是存储雇员数据。 这将会以雇员文档的形式存储:一个文档代表一个雇员。存储数据到 Elasticsearch 的行为叫做索引

    发送一个 put 请求,地址:http://x.x.x.x:9200/megacorp/employee/1,内容为:

    {"first_name" : "John","last_name" :  "Smith","age" :        25,"about" :      "I love to go rock climbing","interests": [ "sports", "music" ]
    }

    点击 Send 后,返回响应结果:

    将 put 请求变为 get 请求读取下刚索引的雇员文档,返回响应结果如下:

    {"_index": "megacorp","_type": "employee","_id": "1","_version": 1,"found": true,"_source": {"first_name": "John","last_name": "Smith","age": 25,"about": "I love to go rock climbing","interests": ["sports","music"]}
    }

    再索引 2 个雇员文档:

    PUT /megacorp/employee/2
    {"first_name" :  "Jane","last_name" :   "Smith","age" :         32,"about" :       "I like to collect rock albums","interests":  [ "music" ]
    }PUT /megacorp/employee/3
    {"first_name" :  "Douglas","last_name" :   "Fir","age" :         35,"about":        "I like to build cabinets","interests":  [ "forestry" ]
    }

Tips:将 HTTP 命令由 PUT 改为 GET 可以用来检索文档,同样的,可以使用 DELETE 命令来删除文档,以及使用 HEAD 指令来检查文档是否存在。如果想更新已存在的文档,只需再次 PUT

  • 轻量级搜索:

    GET /megacorp/employee/_search  #获取所有雇员

    返回结果:

    {"took": 59,"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"]}}]}
    }

    搜索姓氏为 Smith 的雇员:

    GET /megacorp/employee/_search?q=last_name:Smith
  • 表达式搜索:Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂健壮的查询。如:搜索姓氏为 Smith 的雇员且年龄大于 30,使用过滤器 filter ,它支持高效地执行一个结构化查询。

    GET /megacorp/employee/_search
    {"query" : {"bool": {"must": {"match" : {"last_name" : "smith" }},"filter": {"range" : {"age" : { "gt" : 30 } }}}}
    }
  • 全文搜索:Elasticsearch 默认按照相关性得分排序,即每个文档跟查询的匹配程度。

    例:搜索下所有喜欢攀岩(rock climbing)的雇员:

    GET /megacorp/employee/_search
    {"query" : {"match" : {"about" : "rock climbing"}}
    }

    返回 2 条记录,并按照相关性得分排序。

    {"took": 10,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.53484553,"hits": [{"_index": "megacorp","_type": "employee","_id": "1","_score": 0.53484553,"_source": {"first_name": "John","last_name": "Smith","age": 25,"about": "I love to go rock climbing","interests": ["sports","music"]}},{"_index": "megacorp","_type": "employee","_id": "2","_score": 0.26742277,"_source": {"first_name": "Jane","last_name": "Smith","age": 32,"about": "I like to collect rock albums","interests": ["music"]}}]}
    }
  • 短语搜索:它不同于全文搜索,它是精确匹配的。

    GET /megacorp/employee/_search
    {"query" : {"match_phrase" : {"about" : "rock climbing"}}
    }
    {"took": 11,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.53484553,"hits": [{"_index": "megacorp","_type": "employee","_id": "1","_score": 0.53484553,"_source": {"first_name": "John","last_name": "Smith","age": 25,"about": "I love to go rock climbing","interests": ["sports","music"]}}]}
    }
  • 高亮搜索:自动将匹配到的词语加上高亮标签。

    GET /megacorp/employee/_search
    {"query" : {"match_phrase" : {"about" : "rock climbing"}},"highlight": {"fields" : {"about" : {}}}
    }

三、Spring Boot 中使用 ElasticSearch

IDEA 通过 Spring Initializr 创建 Spring Boot 项目:

Spring Boot 可以使用下图中标注的方法来使用 ElasticSearch。

  • 使用 jest 方式:

    从上图中可知,jest 自动配置类还未生效,需要导入类 JestClient,所以添加 Maven 依赖。

    <!-- https://mvnrepository.com/artifact/io.searchbox/jest -->
    <dependency><groupId>io.searchbox</groupId><artifactId>jest</artifactId><version>5.3.4</version>
    </dependency>
    

    配置 jest.uris:

    spring.elasticsearch.jest.uris=http://x.x.xx.:9200/

    创建一个 Java Bean:

    package com.yunche.elasticsearch.bean;import io.searchbox.annotations.JestId;/*** @ClassName: Article* @Description:* @author: yunche* @date: 2019/02/04*/
    public class Article {@JestId //主键private Integer id;private String name;private String author;private String content;public Integer getId() {return id;}@Overridepublic String toString() {return "Article{" +"id=" + id +", name='" + name + '\'' +", author='" + author + '\'' +", content='" + content + '\'' +'}';}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
    }

    单元测试:

    package com.yunche.elasticsearch;import com.yunche.elasticsearch.bean.Article;
    import io.searchbox.client.JestClient;
    import io.searchbox.core.Index;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException;@RunWith(SpringRunner.class)
    @SpringBootTest
    public class ElasticsearchApplicationTests {@Testpublic void contextLoads() {}@AutowiredJestClient jestClient;/*** 索引一个文档*/@Testpublic void indexArticle() {Article article = new Article();article.setId(1);article.setAuthor("火星引力");article.setName("逆天邪神");article.setContent("掌天毒之珠,承邪神之血,修逆天之力。一代邪神,君临天下。");//构建一个索引用于索引Index index = new Index.Builder(article).index("yunche").type("novels").build();try {//索引文档jestClient.execute(index);} catch (IOException e) {e.printStackTrace();}}
    }

    方法无异常,获取该文档,结果如下:

      /*** 全文搜索*/@Testpublic void search() {String query = "{\n" +"    \"query\" : {\n" +"        \"match\" : {\n" +"            \"name\" : \"逆天邪神\"\n" +"        }\n" +"    }\n" +"}";Search search = new Search.Builder(query).addIndex("yunche").addType("novels").build();try {SearchResult result = jestClient.execute(search);//打印for (SearchResult.Hit<Article, Void> hit : result.getHits(Article.class)) {System.out.println(hit.source);} /*Output:Article{id=1, name=' 逆天邪神 ', author=' 火星引力 ', content=' 掌天毒之珠,承邪神之血,修逆天之力。一代邪神,君临天下。'}*/} catch (IOException e) {e.printStackTrace();}}
  • Spring Data 方式:

    application.properties:

    spring.data.elasticsearch.cluster-name=docker-cluster # 注意填写名字,通过访问 9200 端口返回的 json 数据里面 "cluster_name"节点
    spring.data.elasticsearch.cluster-nodes=x.x.x.x:9300
    • 面向接口的方式

      package com.yunche.elasticsearch.repository;import com.yunche.elasticsearch.bean.Anime;
      import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;/*** @ClassName: AnimeRepository* @Description:* @author: yunche* @date: 2019/02/04*/
      public interface AnimeRepository extends ElasticsearchRepository<Anime, Integer> {
      }
      package com.yunche.elasticsearch.bean;import org.springframework.data.elasticsearch.annotations.Document;/*** @ClassName: Anime* @Description:* @author: yunche* @date: 2019/02/04*/
      //指定索引、类型
      @Document(indexName = "yunche", type = "anime")
      public class Anime {private Integer id;private String name;private String summary;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSummary() {return summary;}public void setSummary(String summary) {this.summary = summary;}
      }
      
      @Autowired
      AnimeRepository animeRepository;/*** 以面向接口的方式使用 ES,* 索引一个动漫文档*/
      @Test
      public void test01() {Anime anime = new Anime();anime.setId(1);anime.setName("五等分的花嫁");anime.setSummary("一直过着贫困生活的高中二年级学生·上杉风太郎,找到了一份条件非常好的家庭教师兼职。然而,要教导的学生居然是同级生!而且还是五胞胎!!虽然都是美少女,但同时也是“将要留级”、“讨厌学习”的问题学生们!最开始的任务就是要取得这些女孩们的信任……!?每天都热闹喧嚣!中野家的五姐妹所带来的可爱度 500%的五个不一样的恋爱喜剧,就此开幕!!");animeRepository.index(anime);
      }
      public interface AnimeRepository extends ElasticsearchRepository<Anime, Integer> {//类似于 JPA 面向接口,只需定义方法不需要实现List<Anime> findAnimeByNameLike(String name);
      }
      /*** 测试下搜索*/
      @Test
      public void test02() {NativeSearchQuery searchQuery = new NativeSearchQuery(QueryBuilders.matchQuery("summary", "五胞胎 美少女"));for (Anime anime : animeRepository.search(searchQuery)) {System.out.println(anime.getSummary());}
      }/*** 模糊查找*/
      @Test
      public void test03() {for (Anime anime : animeRepository.findAnimeByNameLike("五等分")) {System.out.println(anime.getSummary());}
      }
    • ElasticsearchTemplate

      @Autowired
      public ElasticsearchTemplate template;
      /*** 索引一个 Anime 文档*/
      @Test
      public void test04() {Anime anime = new Anime();anime.setId(2);anime.setName("约会大作战");anime.setSummary("人类遭遇了名为“空间震”的新型灾害。震荡空间、将一切破坏殆尽的这一灾厄,是由于存在于临界的精灵出现这个世界上时而发生的。为了阻止空间震,使人类免受灾厄而必须采取的措施,是使用武力歼灭精灵,或者是——“与其约会,使其娇羞”!让精灵娇羞,再通过“接吻”即可封印其力量——拥有这种能力的高中生·五河士道,为了人类的和平,也为了拯救精灵们——士道展开了和她们之间的“约会”。对士道敞开心扉的精灵·十香、四糸乃、琴里、耶俱矢、夕弦、美九。为了歼灭精灵而行动的“AST”。企图利用精灵的”DEM”。尝试与精灵和平交流的“拉塔托斯克”。以及,需要令其娇羞的新精灵——围绕着这一切,新的战争(约会)开始了——");IndexQuery indexQuery = new IndexQueryBuilder().withIndexName("yunche").withType("anime").withId(anime.getId().toString()).withObject(anime).build();template.index(indexQuery);
      }
      @Test
      public void test05() {NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery("五").field("summary")).build();for (Anime anime : template.queryForPage(searchQuery, Anime.class)) {System.out.println(anime.getName());}
      } /*outPut:
      五等分的花嫁
      约会大作战
      */

四、参考资料

尚硅谷.Spring Boot 高级

转载于:https://www.cnblogs.com/yunche/p/10352144.html

Spring Boot 与ElasticSearch相关推荐

  1. Elasticsearch学习(3) spring boot整合Elasticsearch的原生方式

    前面我们已经介绍了spring boot整合Elasticsearch的jpa方式,这种方式虽然简便,但是依旧无法解决我们较为复杂的业务,所以原生的实现方式学习能够解决这些问题,而原生的学习方式也是E ...

  2. Elasticsearch实战篇——Spring Boot整合ElasticSearch

    2019独角兽企业重金招聘Python工程师标准>>> 当前Spring Boot很是流行,包括我自己,也是在用Spring Boot集成其他框架进行项目开发,所以这一节,我们一起来 ...

  3. 第 4-8 课:Spring Boot 集成 ElasticSearch

    ElasticSearch 是⼀个开源的搜索引擎,建⽴在⼀个全⽂搜索引擎库 Apache Lucene™ 基础之上. Lucene 可以说是当下最先进.⾼性能.全功能的搜索引擎库--⽆论是开源还是私有 ...

  4. spring boot集成Elasticsearch客户端

    spring boot整合Elasticsearch客户端 在spring boot程序应用中集成Elasticsearch客户端,并通过配置对连接进行管理. Elasticsearch的客户端Jav ...

  5. ElasticSearch实战篇 - Spring Boot 整合 ElasticSearch

    点击上方 Java后端,选择 设为星标 优质文章,及时送达 作者:冯文议 链接:segmentfault.com/a/1190000018625101 当前Spring Boot很是流行,包括我自己, ...

  6. Spring Boot整合elasticsearch实现全文检索

    文章目录 1.引入 1.1 Luence 1.2 Solr 1.3 ElasticSearch 2. ElasticSearch安装 2.1 云服务器安装 2.1.1. docker安装 2.1.2 ...

  7. Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询

    运行环境:JDK 7 或 8,Maven 3.0+ 技术栈:SpringBoot 1.5+,ElasticSearch 2.3.2 本文提纲 一.ES 的使用场景 二.运行 springboot-el ...

  8. Spring Boot 之 elasticsearch

    elasticsearch详解 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用 ...

  9. Spring Boot 集成 Elasticsearch 实战

    今天讲解下如何使用 Spring Boot 结合 ES. 可以在 ES 官方文档中发现,ES 为 Java REST Client 提供了两种方式的 Client:Java Low Level Cli ...

  10. Spring Boot 集成 Elasticsearch

    Elasticsearch (简称ES) 是一个基于 Lucene 的分布式.高扩展.高实时的搜索与数据分析引擎.本章介绍 Spring Boot 应用集成 Elasticsearch ,通过 Spr ...

最新文章

  1. Ubuntu安装python3.7,并将python链接指向python3.7
  2. iOS 四种保存数据的方式!
  3. flask-bootstrap-高亮-下划线-删除线-加粗-斜体
  4. thinkphp mysql批量入库_ThinkPHP3.2框架使用addAll()批量插入数据的方法
  5. SQL with(nolock)详解
  6. Cannot start compilation:the output path is not specifired for module “xxx“.Specify the output path
  7. c语言subscripted_c语言。数组的问题。急!
  8. Silverlight 打印
  9. SPI和RAM IP核
  10. ubuntu 20.04 快速开启TCP BBR实现高效单边加速
  11. typora 分割线_实战 | 五分钟,使用Typora+PicGo提升百倍写作效率
  12. python步长为负时的情况
  13. Linux内核之XArray
  14. Zabbix-server安装后的故障处理及Zabbix-agent的配置添加过程
  15. 老板说,我请你来,不是叫你无脑拷贝的,竟然在线上搞出这么大的一个BUG......
  16. Vue:vue借助全局过滤器、moment、实现实时更新时间
  17. linux 动态链接库 函数共享,LINUX动态链接库高级应用(etc/ld.so.conf)共享动态链接库...
  18. 炸群java脚本,跪求微信炸群代码_跪求以下java程序的源代码
  19. Unity3D 《坦克大战》案例源码过程
  20. android打印机驱动4521,三星打印机驱动官方下载

热门文章

  1. 怎样去除视频水印?快速去除视频水印的方法
  2. 【U8】存货【收发存汇总表】的结存金额与【存货与总账对账】中存货的结存金额不一致。
  3. windows计算机查看里设置,怎么让电脑像手机一样屏幕常亮呢,看这里,WIN10系统下如何设置电脑屏幕...
  4. window下访问同局域网中的redis服务端口问题Warning: no config file specified, using the default config. In order to..
  5. c语言flip用法,C++ bitset::flip()用法及代码示例
  6. 吃鸡最强攻略!内附170行Python代码!
  7. 轻量级实时语义分割:Guided Upsampling Network for Real-Time Semantic Segmentation
  8. 解决Could not find method ndkVersion() for arguments on object of type com.android.build.问题
  9. 移除JSON对象中的某个属性
  10. css隐藏表格线,用CSS改变(隐藏)表格边框样式