【Spring全家桶系列超全整理之SpringBoot框架】9 SpringBoot整合elasticsearch检索功能

本文介绍了Elasticsearch的基础知识,包括其与Lucene的关系、JSON格式、CRUD操作。通过实例展示了如何在Docker中安装Elasticsearch并进行数据的增删查改。接着讲解了SpringBoot如何整合Elasticsearch,分别使用Jest和SpringDataElasticSearch两种方式进行操作,并给出相应的配置和测试代码。
摘要由CSDN通过智能技术生成

本文介绍SpringBoot相关内容。和【跨考菌】一起加油吧~

在这里插入图片描述

如果你有收获,记得帮博主一键三连哦😊


1 检索概述

1.1 Elasticsearch概述

在这里插入图片描述
我们今天学习的Elasticsearch其实是整合了Lucene框架。

1.2 相关概念

在这里插入图片描述
在这里插入图片描述

2 Elastic文档学习

学习文档地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html

接下来我们根据文档中的介绍,学习elastic的基本用法,首先需要安装elastic:

2.1 安装elastic

拉取镜像:

docker pull elasticsearch:2.4.6 # 这里安装了2.4.6版本,为了和后面的演示项目兼容

查看镜像:

[root@kafka2 ~]# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
docker.io/rabbitmq             3-management        800294d91e31        2 weeks ago         198 MB
jpress                         latest              773e1fd1b1b9        2 months ago        313 MB
nginx                          v3                  89f9edd3eb63        2 months ago        133 MB
<none>                         <none>              afebc12a7cbe        2 months ago        72.9 MB
docker.io/mysql                latest              4f1413420360        2 months ago        545 MB
docker.io/elasticsearch        latest              5acf0e8da90b        2 years ago         486 MB
docker.io/elasticsearch        2.4.6               5e9d896dc62c        2 years ago         479 MB
hub.c.163.com/library/tomcat   latest              72d2be374029        3 years ago         292 MB
hub.c.163.com/library/nginx    latest              46102226f2fd        3 years ago         109 MB

创建docker容器:

[root@kafka2 ~]# docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9201:9200 -p 9301:9300 --restart=always --name ES02 5e9d896dc62c
460013879a8c515953df0bf105782403ec0d7b75bcf9bb6277294968b849a456

开放端口:

[root@kafka2 ~]# firewall-cmd --zone=public --add-port=9201/tcp --permanent

success
[root@kafka2 ~]# 
[root@kafka2 ~]# firewall-cmd --zone=public --add-port=9301/tcp --permanent
success
[root@kafka2 ~]# firewall-cmd --reload

访问测试:
在这里插入图片描述

2.2 JSON格式化

Elasticsearch 使用 JavaScript Object Notation(或者 JSON)作为文档的序列化格式。JSON 序列化为大多数编程语言所支持,并且已经成为 NoSQL 领域的标准格式。 它简单、简洁、易于阅读。

下面这个 JSON 文档代表了一个 user 对象:

{
    "email":      "john@smith.com",
    "first_name": "John",
    "last_name":  "Smith",
    "info": {
        "bio":         "Eco-warrior and defender of the weak",
        "age":         25,
        "interests": [ "dolphins", "whales" ]
    },
    "join_date": "2014/05/01"
}

2.3 elastic索引

elastic支持rest风格的crud。

PUT:添加数据
DELETE:删除数据
GET:查询数据

下面以员工信息存取为例:

  • 每个员工索引一个文档,文档包含该员工的所有信息。
  • 每个文档都将是 employee 类型 。
  • 该类型位于 索引 megacorp 内。
  • 该索引保存在我们的 Elasticsearch 集群中。

2.3.1 PUT存数据

用postman依次存储下面三条数据:

PUT /megacorp/employee/1
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
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" ]
}

在这里插入图片描述

2.3.2 GET取数据

GET /megacorp/employee/1

返回结果包含了文档的一些元数据,以及 _source 属性,内容是 John Smith 雇员的原始 JSON 文档:

{
  "_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.3.3 轻量搜索

GET /megacorp/employee/_search # 搜索所有的雇员

可以看到,我们仍然使用索引库 megacorp 以及类型 employee,但与指定一个文档 ID 不同,这次使用 _search 。返回结果包括了所有三个文档,放在数组 hits 中。一个搜索默认返回一条结果。
在这里插入图片描述
也可以根据某个字段进行查询:

GET /megacorp/employee/_search?q=last_name:Smith

我们仍然在请求路径中使用 _search 端点,并将查询本身赋值给参数 q= 。返回结果给出了所有的 Smith:

{
   ...
   "hits": {
      "total":      2,
      "max_score":  0.30685282,
      "hits": [
         {
            ...
            "_source": {
               "first_name":  "John",
               "last_name":   "Smith",
               "age":         25,
               "about":       "I love to go rock climbing",
               "interests": [ "sports", "music" ]
            }
         },
         {
            ...
            "_source": {
               "first_name":  "Jane",
               "last_name":   "Smith",
               "age":         32,
               "about":       "I like to collect rock albums",
               "interests": [ "music" ]
            }
         }
      ]
   }
}

2.3.4 查询表达式

当查询条件比较复杂的时候,可以将查询条件放到json中,作为参数进行查询:

GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}

在这里插入图片描述
更复杂的搜索:

同样搜索姓氏为 Smith 的员工,但这次我们只需要年龄大于 30 的。查询需要稍作调整,使用过滤器 filter ,它支持高效地执行一个结构化查询。

GET /megacorp/employee/_search
{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "last_name" : "smith" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            }
        }
    }
}

2.3.5 全文搜索

搜索下所有喜欢攀岩(rock climbing)的员工:(只要和你的短语相关的都会列举出来)

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

显然我们依旧使用之前的 match 查询在about 属性上搜索 “rock climbing” 。得到两个匹配的文档:

{
   ...
   "hits": {
      "total":      2,
      "max_score":  0.16273327,
      "hits": [
         {
            ...
            "_score":         0.16273327, 
            "_source": {
               "first_name":  "John",
               "last_name":   "Smith",
               "age":         25,
               "about":       "I love to go rock climbing",
               "interests": [ "sports", "music" ]
            }
         },
         {
            ...
            "_score":         0.016878016, 
            "_source": {
               "first_name":  "Jane",
               "last_name":   "Smith",
               "age":         32,
               "about":       "I like to collect rock albums",
               "interests": [ "music" ]
            }
         }
      ]
   }
}

2.3.6 短语搜索

精准匹配一个短语。

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

返回结果仅有 John Smith 的文档。

{
   ...
   "hits": {
      "total":      1,
      "max_score":  0.23013961,
      "hits": [
         {
            ...
            "_score":         0.23013961,
            "_source": {
               "first_name":  "John",
               "last_name":   "Smith",
               "age":         25,
               "about":       "I love to go rock climbing",
               "interests": [ "sports", "music" ]
            }
         }
      ]
   }
}

3 spring整合elasticsearch

查看springboot整合的包,可以发现有2个elasticsearch的包:
在这里插入图片描述
说明springboot有2种方式来和elasticsearch交互:

  • Jest(默认不生效):需要导入jest的工具包(io.searchbox.client.JestClient)
  • SpringData ElasticSearch【ES版本有可能不合适】

3.1 Jest操作elastic

3.1.1 引入pom依赖

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

在这里插入图片描述
在Jest的自动配置类中可以发现,为我们自动注入了JestClient客户端,方便的进行对elastic的操作。

3.1.2 配置application.properities文件参数

spring.elasticsearch.jest.uris=http://192.168.229.140:9200

Jest是通过http的方式与9200端口进行交互的。

3.1.3 测试

	@Autowired
    JestClient jestClient;

	@Test
    public void contextLoads() {
        //1、给Es中索引(保存)一个文档;
        Article article = new Article();
        article.setId(1);
        article.setTitle("好消息");
        article.setAuthor("zhangsan");
        article.setContent("Hello World");

        //构建一个索引功能
        Index index = new Index.Builder(article).index("atguigu").type("news").build();

        try {
            //执行
            jestClient.execute(index);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //测试搜索
    @Test
    public void search() {

        //查询表达式
        String json = "{\n" +
                "    \"query\" : {\n" +
                "        \"match\" : {\n" +
                "            \"content\" : \"hello\"\n" +
                "        }\n" +
                "    }\n" +
                "}";

        //更多操作:https://github.com/searchbox-io/Jest/tree/master/jest
        //构建搜索功能
        Search search = new Search.Builder(json).addIndex("atguigu").addType("news").build();

        //执行
        try {
            SearchResult result = jestClient.execute(search);
            System.out.println(result.getJsonString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

说明:在上面的Article类上可以使用我们的@JestId注解标注为ID。

public class Article {

    @JestId
    private Integer id;
    private String author;
    private String title;
    private String content;

3.2 springdata操作elastic

3.2.1 引入pom依赖

<!--SpringBoot默认使用SpringData ElasticSearch模块进行操作-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

3.2.2 配置cluster信息

spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=192.168.229.140:9301

这里的端口是刚才虚拟机配置elastic的时候暴露的端口。

3.2.3 编写实体类和对应接口

// 定义了索引和type
@Document(indexName = "atguigu",type = "book")
public class Book {
    private Integer id;
    private String bookName;
    private String author;
    xxx
// 泛型的第一个字段是实体类的类型,第二个字段是实体类的主键的类型
public interface BookRepository extends ElasticsearchRepository<Book,Integer> {

}

3.2.4 测试

 @Autowired
    BookRepository bookRepository;

    @Test
    public void test02() {
		Book book = new Book();
		book.setId(1);
		book.setBookName("西游记");
		book.setAuthor("吴承恩");
		bookRepository.index(book); // 存储数据

BookReporitory所有方法:
在这里插入图片描述

3.2.5 自定义方法

参考文档:https://docs.spring.io/spring-data/elasticsearch/docs/3.0.6.RELEASE/reference/html/#elasticsearch.repositories

public interface BookRepository extends ElasticsearchRepository<Book,Integer> {

    //参照
    // https://docs.spring.io/spring-data/elasticsearch/docs/3.0.6.RELEASE/reference/html/
   public List<Book> findByBookNameLike(String bookName);

}
for (Book book : bookRepository.findByBookNameLike("游")) {
			System.out.println(book);
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值