首页 > 其他分享 >SpringBoot 1x 系列之(十)Spring Boot与检索

SpringBoot 1x 系列之(十)Spring Boot与检索

时间:2024-02-28 10:16:00浏览次数:21  
标签:SpringBoot 1x Boot must 文档 Elasticsearch bool true name

Spring Boot与检索

ElasticSearch

1. ElasticSearch简介

1)Java语言编写的开源全文搜索引擎。

2)用于快速的存储、搜索和分析海量数据。

3)是一个分布式搜索服务。

4)提供Restful API,通过发送请求的方式就可以将ElasticSearch用起来。

5)底层基于Lucene(开源的搜索引擎软件工具包)

2. Docker安装ElasticSearch

#这里安装的是5.6.13版本,安装8.2.0,通过相同的方式启动是失败的
docker pull elasticsearch:5.6.13

#web通信端口:9200
#分布式环境时各个节点之间通信的端口:9300
#初始的堆内存大小:-Xms256m,如果不指定,默认初始占用2G的堆内存空间
#最大使用的堆内存大小:-Xmx256m
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name ES02 3fd2f723b598

出现下面的界面就是安装成功了

3. Elasticsearch快速入门

官方文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html

3.1 介绍

1)面向文档,存储整个对象或文档,方便对文档进行索引、检索、排序和过滤

2)使用JSON作为文档的序列化格式,使用JSON的好处是轻量级、跨平台

比如存储的user对象

{
    "email":      "[email protected]",
    "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"
}

3.2 基本概念

1)索引(动词):给ElasticSearch中存储数据的行为就叫做索引,实际含义可以和存储划等号

2)索引(名词):一个 Elasticsearch 集群可以 包含多个 索引,类比Mysql中的数据库

3)类型:每个索引可以包含多个类型,类比Mysql中的数据表

4)文档:不同的类型存储着多个文档,类比Mysql中数据表的记录,每张表有多条记录,每个类型下有多个文档

5)属性:每个文档有多个属性,类比Mysql中记录的每个字段

3.3 基本操作

3.3.1 索引文档(C)

实际上就是将数据存储到ElasticSearch中

请求地址格式:ElasticSearch服务器地址:web端口/索引/类型/文档ID

​ 如:http://192.168.37.128:9200/megacorp/employee/1

请求方式必须是PUT

3.3.2 检索文档(R)

请求地址格式不变,请求方式变为GET

3.3.3 更新文档(U)

再次索引文档即可,更新后version的值会增加

3.3.4 删除文档(D)

请求地址格式不变,请求方式变为DELETE

3.3.5 检查是否存在指定文档

检查ElasticSearch中是否存在指定的文档,根据响应结果中的Status判断

3.3.6 轻量搜索

请求地址格式:ElasticSearch服务器地址:web端口/索引/类型/_search[查询字符串]

​ 其中查询字符串是可选的,如果不加查询字符串,默认查所有

​ 如果携带查询字符串,按条件进行查询

​ 如:http://192.168.37.128:9200/megacorp/employee/?q=last_name:Smith

​ 查询所有文档中last_name字段的值为Smith的文档

请求方式必须是GET

3.3.7 查询表达式搜索

查询表达式:给ElasticSearch提交一串JSON表达式,JSON中指定查询规则

请求地址格式:ElasticSearch服务器地址:web端口/索引/类型/_search

请求体:

{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}

请求方式:POST

可以进行更复杂的查询,比如使用filter

只需要改变查询表达式即可

{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "last_name" : "smith" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            }
        }
    }
}
3.3.7 全文搜索

指定属性值进行查询,查询出文档中属性的属性值包含我们指定的属性值的文档

请求地址:ElasticSearch服务器地址:web端口/索引/类型/_search

请求体:

{
    "query" : {
        "match" : {
            "about" : "rock climbing"
        }
    }
}

​ 比如这里就要查文档的about属性包含rock climbing的文档,并不是绝对比配才能够查到,包含其中的一个单词,比如climbing也是能够查出来的,匹配程度可以通过响应中_score(相关性得分)的大小进行区分。

请求方式:GET

3.3.8 短语搜索

与全文搜索不同,短语搜索查询时会将查询条件中的属性值作为一个完整的单词进行精确匹配

请求地址:ElasticSearch服务器地址:web端口/索引/类型/_search

请求体:

{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    }
}

请求方式:GET

3.3.9 高亮搜索

通过查询表达式中的highlight 参数结合短语搜索进行高亮搜索

请求地址:ElasticSearch服务器地址:web端口/索引/类型/_search

请求体:

{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}

请求方式:GET

4. SpringBoot整合Jest操作Elasticsearch

Jest:ElasticSearch客户端工具,通过HTTP方式与Elasticsearch交互。

SpringBoot默认支持两种技术来和ES交互:
1)Jest (默认不生效)
​ 需要导入Jest的工具包(io.searchbox.client.JestClient)
2)SpringData ELasticSearch

4.1 引入依赖

引入依赖时需要注意Jest和Elasticsearch的版本对应关系

Jest和ES版本对应关系:Jest.x对应ES.x,比如,Es是5.x.x的,Jest也需要是5.x.x的

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

4.2 自动配置

Jest对Elasticsearch的自动配置:org.springframework.boot.autoconfigure.elasticsearch

1)JestAutoConfiguration

​ 向容器中放了JestClient,用来操作Elasticsearch

2)需要在全局配置中配置spring.elasticsearch.jest.uris ,默认是http://localhost:9200

4.3 全局配置

spring:
  elasticsearch:
    jest:
      uris: http://192.168.37.128:9200

4.4 Jest操作Elasticsearch

JavaBean

public class Article {

    //@JestId:标识这是一个主键
    @JestId
    private Integer id;
    private String author;
    private String title;
    private String content;
    
    //省略了get、set方法
    ...
}
    @Autowired
    JestClient jestClient;

    /**
     * 索引(存储)一个文档
     */
    @Test
    public void testJestClient(){
        Article article = new Article();
        article.setId(1);
        article.setAuthor("zhangsan");
        article.setTitle("好消息");
        article.setContent("Hello world");

//        构建索引(存储)功能
//        Builder(article):Builder的参数指定了存储哪个对象
//        .index("atguigu").type("test"):指定了存储到哪个索引(名词)下的哪个类型,Id已经在Article中通过@JestId注解指定了,所以这里不需要再指定
        Index index = new Index.Builder(article).index("atguigu").type("test").build();

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

    /**
     * 全文搜索
     */
    @Test
    public void testJestClient2(){

//        创建查询表达式,全文搜索content属性包含Hello值的文档
        String json = "{\n" +
                "    \"query\" : {\n" +
                "        \"match\" : {\n" +
                "            \"content\" : \"Hello\"\n" +
                "        }\n" +
                "    }\n" +
                "}";

//        构建搜索功能
//        Builder(json):Builder的参数指定了查询表达式
//        .addIndex("atguigu").addType("test"):指定了要查找哪个索引(名词)下的哪个类型下的文档
        Search search = new Search.Builder(json).addIndex("atguigu").addType("test").build();

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

    }

5. SpringBoot整合SpringData Elasticsearch操作Elasticsearch

5.1 引入依赖

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

5.2 自动配置

SpringData对Elasticsearch的自动配置:org.springframework.boot.autoconfigure.data.elasticsearch

1)ElasticsearchAutoConfiguration

​ 向容器中放了Client,需要配置节点信息(clusterNodes和clusterName),通过Client来操作Elasticsearch
2)ElasticsearchDataAutoConfiguration

​ 向容器中放了ElasticsearchTemplate ,用来操作Elasticsearch

3)ElasticsearchRepositoriesAutoConfiguration

​ 需要编写一个ElasticsearchRepository的子接口来操作Elasticsearch,类似JPA的编程方式

5.3 全局配置

主配置文件中配置节点信息

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 192.168.37.128:9300

cluster-name

单节点的cluster-nodes就是ip+分布式环境时各个节点之间通信的端口

启动后报错,这是由于Spring Data Elasticsearch与Elasticsearch版本不适配造成的

Spring Data Elasticsearch与Elasticsearch版本适配如下图:

我的Spring Data Elasticsearch版本是

Elasticsearch版本是

版本不适配,处理方法有两种

1)升级SpringBoot版本,从而升级Spring Data Elasticsearch的版本

2)安装对应版本的Elasticsearch

我这里选择第二种方法,首先查看我的Spring Data Elasticsearch引入的Elasticsearch版本是多少

那么我就要安装2.4.6版本的Elasticsearch

重新启动,不再有报错,问题解决

5.4 创建ElasticsearchRepository的子接口操作Elasticsearch

编写一个ElasticsearchRepository的子接口

//两个泛型的值:要存取的数据类型,id的类型
public interface BookRepository extends ElasticsearchRepository<Book, Integer> {
}

JavaBean

//indexName = "atguigu":指定要存储到哪个索引
//type = "book":指定要存储到哪个类型
//文档id不需要单独指定,因为在book对象中已经传入了id
@Document(indexName = "atguigu", type = "book")
public class Book {

    private Integer id;
    private String author;
    private String title;
 	
  	//省略了get、set、toString方法
  	...
}
@Autowired
BookRepository repository;

//测试索引一个文档
@Test
public void test01(){
    Book book = new Book();
    book.setId(15);
    book.setAuthor("lisidasdd");
    book.setTitle("wainasdsfi");
    repository.index(book);
}

ElasticsearchRepository已经内置了很多的方法操作Elasticsearch,同时也支持自定义方法,但是方法名必须按照要求来

首先在子接口中定义方法

public interface BookRepository extends ElasticsearchRepository<Book, Integer> {
    public List<Book> findByTitleLike(String bookName);
}
    @Autowired
    BookRepository repository;

    @Test
    public void test01(){
        for (Book book : repository.findByTitleLike("wai")) {
            System.out.println(book);
        }
        ;
    }

ElasticsearchRepository支持的自定义方法名和对应的查询表达式如下

Keyword Sample Elasticsearch Query String
And findByNameAndPrice {"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
Or findByNameOrPrice {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
Is findByName {"bool" : {"must" : {"field" : {"name" : "?"}}}}
Not findByNameNot {"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
Between findByPriceBetween {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqual findByPriceLessThan {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
GreaterThanEqual findByPriceGreaterThan {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
Before findByPriceBefore {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
After findByPriceAfter {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
Like findByNameLike {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWith findByNameStartingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWith findByNameEndingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/Containing findByNameContaining {"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}
In findByNameIn(Collection<String>names) {"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotIn findByNameNotIn(Collection<String>names) {"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
Near findByStoreNear Not Supported Yet !
True findByAvailableTrue {"bool" : {"must" : {"field" : {"available" : true}}}}
False findByAvailableFalse {"bool" : {"must" : {"field" : {"available" : false}}}}
OrderBy findByAvailableTrueOrderByNameDesc {"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

同时也支持自己设定执行的查询表达式

参考网站:https://docs.spring.io/spring-data/elasticsearch/docs/3.0.6.RELEASE/reference/html/#elasticsearch.query-methods

标签:SpringBoot,1x,Boot,must,文档,Elasticsearch,bool,true,name
From: https://www.cnblogs.com/wzzzj/p/18039119

相关文章

  • SpringBoot 1x 系列之(九)Spring Boot与消息
    SpringBoot与消息JMS、AMQP、RabbitMQ1.概述消息服务的两个常见规范(消息代理规范):JMS、AMQPJMS(JavaMessageService)JAVA消息服务:​ 基于JVM消息代理的规范。ActiveMQ、HornetMQ是JMS实现AMQP(AdvancedMessageQueuingProtocol)高级消息队列协议​ 也是一个消息代理的规范......
  • SpringBoot 1x 系列之(八)Spring Boot与缓存
    SpringBoot与缓存JSR-107、Spring缓存抽象、整合Redis缓存:加速系统访问,提升系统性能热点数据、临时数据(如验证码)1.JSR-1071.1背景统一缓存的开发规范及提升系统的扩展性,J2EE发布了JSR-107缓存规范1.2JSR107简介CacheManager与Cache的关系,类比连接池与连接涉及的包ja......
  • SpringBoot 1x 系列之(七)自定义starter
    自定义starterstarters原理、自定义starters如何自定义starter:​ 1、这个场景需要使用到的依赖是什么?​ 2、如何编写自动配置@Configuration//指定这个类是一个配置类@ConditionalOnXXX//在指定条件成立的情况下自动配置类生效@AutoConfigureAfter//指定自动配置类的......
  • SpringBoot 1x 系列之(六)Spring Boot启动配置原理
    SpringBoot启动配置原理启动原理、运行流程、自动配置原理几个重要的事件回调机制(这几个事件回调机制可供我们进行干预)配置在META-INF/spring.factoriesApplicationContextInitializerSpringApplicationRunListener只需要放在ioc容器中(@Component标注)ApplicationRunnerCo......
  • SpringBoot 1x 系列之(五)SpringBoot与数据访问
    SpringBoot与数据访问JDBC、MyBatis、SpringDataJPASpringBoot底层是使用的SpringData作为数据访问的默认处理方式。1.整合基本JDBC与数据源Pom依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><......
  • SpringBoot 1x 系列之(四)Spring Boot与Web开发
    SpringBoot与Web开发Thymeleaf、Web定制、容器定制1.如何使用SpringBoot创建SpringBoot应用,选中我们需要的模块SpringBoot已经默认将这些场景配置好了,我们只需要在配置文件中指定少量配置就可以运行起来编写业务代码2.SpringBoot对静态资源的映射规则普通的web应用......
  • SpringBoot 1x 系列之(三)SpringBoot与日志
    SpringBoot与日志日志框架、日志配置1.日志框架JDBC和数据库驱动:JDBC是统一的接口层(抽象层),面向JDBC进行开发,而不直接面向数据库驱动,这样的好处是数据库驱动会不断的出现新产品,如果直接面向数据库驱动开发,那么,每次更换数据库驱动,开发的代码就要做相应的调整,而面向JDBC开发,不管......
  • SpringBoot 1x 系列之(二)SpringBoot 配置
    SpringBoot配置配置文件、加载顺序、配置原理1.配置文件SpringBoot默认使用两种类型的配置文件作为一个全局配置文件,配置文件名固定,用于修改SpringBoot自动配置的默认值application.propertiesapplication.y(a)ml1.1YAML简介YAML(YAMLAin'tMarkupLanguage)递归缩写......
  • SpringBoot 1x 系列之(一)SpringBoot 入门
    SpringBoot入门SpringBoot和微服务概念的简介、SpringBootHelloWorld入门程序、内部原理1.SpringBoot简介简化Spring应用开发(整个J2EE开发)的一个框架整个Spring技术栈的一个大整合.........J2EE开发的一站式解决方案注:SpringBoot使用嵌入式的Servlet容器,应用无......
  • spring boot 中使用MybatisPlus的自动填充createTime和updateTime
    首先需要在实体类的字段上加上注解,并且将类型更改为LocalDateTime@TableField(fill=FieldFill.INSERT)@JsonInclude(value=JsonInclude.Include.NON_NULL)@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss")privateLocalDateTimecreateTime;@TableFie......