springboot实体映射到数据库_SpringBoot 操作 ElasticSearch 详解

本文详细介绍了如何使用SpringBoot操作ElasticSearch,包括ElasticSearch简介、基础概念、项目依赖配置、索引和文档操作、查询及聚合查询等实战示例。
摘要由CSDN通过智能技术生成
点击上方☝ SpringForAll社区  轻松关注! 及时获取有趣有料的技术文章

本文来源:http://www.mydlq.club/article/64/

一、ElasticSearch 简介

. 1、简介

. 2、特性

. 3、使用场景

. 二、ElasticSearch 基础概念

. 1、ElaticSearch 和 DB 的关系

. 2、索引

. 3、文档

. 4、映射

. 三、SpringBoot 项目引入 ElasticSearch 依赖

. 1、Maven 引入相关依赖

. 2、ElasticSearch 连接配置

. 四、索引操作示例

. 1、Restful 操作示例

. 2、Java 代码示例

. 五、文档操作示例

. 1、Restful 操作示例

. 2、Java 代码示例

. 六、插入初始化数据

. 1、单条插入

. 2、批量插入

. 3、查询数据

. 七、查询操作示例

. 1、精确查询(term)

. 2、匹配查询(match)

. 3、模糊查询(fuzzy)

. 4、范围查询(range)

. 5、通配符查询(wildcard)

. 6、布尔查询(bool)

. 八、聚合查询操作示例

. 1、Metric 聚合分析

. 2、Bucket 聚合分析

. 3、Metric 与 Bucket 聚合分析


参考地址:

  • 百度百科

  • 博文示例项目 Github 地址:https://github.com/my-dlq/blog-example/tree/master/springboot/springboot-elasticsearch-example

系统环境:

  • SpringBoot 版本:2.2.4

  • ElasticSearch 版本:6.5.3

一、ElasticSearch 简介

1、简介

ElasticSearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多员工能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 是用 Java 语言开发的,并作为 Apache 许可条款下的开放源码发布,是一种流行的企业级搜索引擎。

ElasticSearch 用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

2、特性

  • 分布式的文档存储引擎

  • 分布式的搜索引擎和分析引擎

  • 分布式,支持PB级数据

3、使用场景

  • 搜索领域: 如百度、谷歌,全文检索等。

  • 门户网站: 访问统计、文章点赞、留言评论等。

  • 广告推广: 记录员工行为数据、消费趋势、员工群体进行定制推广等。

  • 信息采集: 记录应用的埋点数据、访问日志数据等,方便大数据进行分析。

二、ElasticSearch 基础概念

1、ElaticSearch 和 DB 的关系

在 Elasticsearch 中,文档归属于一种类型 type,而这些类型存在于索引 index 中,我们可以列一些简单的不同点,来类比传统关系型数据库:

  • Relational DB -> Databases -> Tables -> Rows -> Columns

  • Elasticsearch -> Indices -> Types -> Documents -> Fields

Elasticsearch 集群可以包含多个索引 indices,每一个索引可以包含多个类型 types,每一个类型包含多个文档 documents,然后每个文档包含多个字段 Fields。而在 DB 中可以有多个数据库 Databases,每个库中可以有多张表 Tables,没个表中又包含多行Rows,每行包含多列Columns

2、索引

  • 索引基本概念(indices):

索引是含义相同属性的文档集合,是 ElasticSearch 的一个逻辑存储,可以理解为关系型数据库中的数据库,ElasticSearch 可以把索引数据存放到一台服务器上,也可以 sharding 后存到多台服务器上,每个索引有一个或多个分片,每个分片可以有多个副本。

  • 索引类型(index_type):

索引可以定义一个或多个类型,文档必须属于一个类型。在 ElasticSearch 中,一个索引对象可以存储多个不同用途的对象,通过索引类型可以区分单个索引中的不同对象,可以理解为关系型数据库中的表。每个索引类型可以有不同的结构,但是不同的索引类型不能为相同的属性设置不同的类型。

3、文档

  • 文档(document):

文档是可以被索引的基本数据单位。存储在 ElasticSearch 中的主要实体叫文档 document,可以理解为关系型数据库中表的一行记录。每个文档由多个字段构成,ElasticSearch 是一个非结构化的数据库,每个文档可以有不同的字段,并且有一个唯一的标识符。

4、映射

  • 映射(mapping):

ElasticSearch 的 Mapping 非常类似于静态语言中的数据类型:声明一个变量为 int 类型的变量,以后这个变量都只能存储 int 类型的数据。同样的,一个 number 类型的 mapping 字段只能存储 number 类型的数据。

同语言的数据类型相比,Mapping 还有一些其他的含义,Mapping 不仅告诉 ElasticSearch 一个 Field 中是什么类型的值, 它还告诉 ElasticSearch 如何索引数据以及数据是否能被搜索到。

ElaticSearch 默认是动态创建索引和索引类型的 Mapping 的。这就相当于无需定义 Solr 中的 Schema,无需指定各个字段的索引规则就可以索引文件,很方便。但有时方便就代表着不灵活。比如,ElasticSearch 默认一个字段是要做分词的,但我们有时要搜索匹配整个字段却不行。如有统计工作要记录每个城市出现的次数。对于 name 字段,若记录 new york 文本,ElasticSearch 可能会把它拆分成 new 和 york 这两个词,分别计算这个两个单词的次数,而不是我们期望的 new york

三、SpringBoot 项目引入 ElasticSearch 依赖

下面介绍下 SpringBoot 如何通过 elasticsearch-rest-high-level-client 工具操作 ElasticSearch,这里需要说一下,为什么没有使用 Spring 家族封装的 spring-data-elasticsearch

主要原因是灵活性和更新速度,Spring 将 ElasticSearch 过度封装,让开发者很难跟 ES 的 DSL 查询语句进行关联。再者就是更新速度,ES 的更新速度是非常快,但是 spring-data-elasticsearch 更新速度比较缓慢。

由于上面两点,所以选择了官方推出的 Java 客户端 elasticsearch-rest-high-level-client,它的代码写法跟 DSL 语句很相似,懂 ES 查询的使用其上手很快。

示例项目地址:https://github.com/my-dlq/blog-example/tree/master/springboot/springboot-elasticsearch-example

1、Maven 引入相关依赖

  • lombok: lombok 工具依赖。

  • fastjson: 用于将 JSON 转换对象的依赖。

  • spring-boot-starter-web: SpringBoot 的 Web 依赖。

  • elasticsearch:ElasticSearch: 依赖,需要和 ES 版本保持一致。

  • elasticsearch-rest-high-level-client: 用于操作 ES 的 Java 客户端。

 1<?xml  version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4    <modelVersion>4.0.0modelVersion>
5    <parent>
6        <groupId>org.springframework.bootgroupId>
7        <artifactId>spring-boot-starter-parentartifactId>
8        <version>2.2.4.RELEASEversion>
9        <relativePath/> 
10    parent>
11    <groupId>club.mydlqgroupId>
12    <artifactId>springboot-elasticsearch-exampleartifactId>
13    <version>0.0.1-SNAPSHOTversion>
14    <name>springboot-elasticsearch-examplename>
15    <description>Demo project for Spring Boot ElasticSearchdescription>
16
17    <properties>
18        <java.version>1.8java.version>
19    properties>
20    <dependencies>
21        
22        <dependency>
23            <groupId>org.springframework.bootgroupId>
24            <artifactId>spring-boot-starter-webartifactId>
25        dependency>
26        
27        <dependency>
28            <groupId>org.projectlombokgroupId>
29            <artifactId>lombokartifactId>
30            <optional>trueoptional>
31        dependency>
32        
33        <dependency>
34            <groupId>com.alibabagroupId>
35            <artifactId>fastjsonartifactId>
36            <version>1.2.61version>
37        dependency>
38        
39        <dependency>
40            <groupId>org.elasticsearch.clientgroupId>
41            <artifactId>elasticsearch-rest-high-level-clientartifactId>
42            <version>6.5.4version>
43        dependency>
44        <dependency>
45            <groupId>org.elasticsearchgroupId>
46            <artifactId>elasticsearchartifactId>
47            <version>6.5.4version>
48        dependency>
49    dependencies>
50
51    <build>
52        <plugins>
53            <plugin>
54                <groupId>org.springframework.bootgroupId>
55                <artifactId>spring-boot-maven-pluginartifactId>
56            plugin>
57        plugins>
58    build>
59
60project>

2、ElasticSearch 连接配置

(1)、application.yml 配置文件

为了方便更改连接 ES 的连接配置,所以我们将配置信息放置于 application.yaml 中:

 1#base
2server:
3  port: 8080
4#spring
5spring:
6  application:
7    name: springboot-elasticsearch-example
8#elasticsearch
9elasticsearch:
10  schema: http
11  address: 127.0.0.1:9200
12  connectTimeout: 5000
13  socketTimeout: 5000
14  connectionRequestTimeout: 5000
15  maxConnectNum: 100
16  maxConnectPerRoute: 100

(2)、java 连接配置类

这里需要写一个 Java 配置类读取 application 中的配置信息:

 1import org.apache.http.HttpHost;
2import org.elasticsearch.client.RestClient;
3import org.elasticsearch.client.RestClientBuilder;
4import org.elasticsearch.client.RestHighLevelClient;
5import org.springframework.beans.factory.annotation.Value;
6import org.springframework.context.annotation.Bean;
7import org.springframework.context.annotation.Configuration;
8import java.util.ArrayList;
9import java.util.List;
10
11/**12 * ElasticSearch 配置13 */
14@Configuration
15public class ElasticSearchConfig {
16
17    /** 协议 */
18    @Value("${elasticsearch.schema:http}")
19    private String schema;
20
21    /** 集群地址,如果有多个用“,”隔开 */
22    @Value("${elasticsearch.address}")
23    private String address;
24
25    /** 连接超时时间 */
26    @Value("${elasticsearch.connectTimeout:5000}")
27    private int connectTimeout;
28
29    /** Socket 连接超时时间 */
30    @Value("${elasticsearch.socketTimeout:10000}")
31    private int socketTimeout;
32
33    /** 获取连接的超时时间 */
34    @Value("${elasticsearch.connectionRequestTimeout:5000}")
35    private int connectionRequestTimeout;
36
37    /** 最大连接数 */
38    @Value("${elasticsearch.maxConnectNum:100}")
39    private int maxConnectNum;
40
41    /** 最大路由连接数 */
42    @Value("${elasticsearch.maxConnectPerRoute:100}")
43    private int maxConnectPerRoute;
44
45    @Bean
46    public RestHighLevelClient restHighLevelClient() {
47        // 拆分地址
48        List hostLists = new ArrayList<>();49        String[] hostList = address.split(",");50        for (String addr : hostList) { 51            String host = addr.split(":")[0];52            String port = addr.split(":")[1];53            hostLists.add(new HttpHost(host, Integer.parseInt(port), schema));54        }55        // 转换成 HttpHost 数组56        HttpHost[] httpHost = hostLists.toArray(new HttpHost[]{});57        // 构建连接对象58        RestClientBuilder builder = RestClient.builder(httpHost);59        // 异步连接延时配置60        builder.setRequestConfigCallback(requestConfigBuilder -> { 61            requestConfigBuilder.setConnectTimeout(connectTimeout);62            requestConfigBuilder.setSocketTimeout(socketTimeout);63            requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeout);64            return requestConfigBuilder;65        });66        // 异步连接数配置67        builder.setHttpClientConfigCallback(httpClientBuilder -> { 68            httpClientBuilder.setMaxConnTotal(maxConnectNum);69            httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);70            return httpClientBuilder;71        });72        return new RestHighLevelClient(builder);73    }7475}

四、索引操作示例

这里示例会指出通过 Kibana 的 Restful 工具操作与对应的 Java 代码操作的两个示例。

1、Restful 操作示例

创建索引

创建名为 mydlq-user 的索引与对应 Mapping。

 1PUT /mydlq-user
2{
3  "mappings": {
4    "doc": {
5      "dynamic": true,
6      "properties": {
7        "name": {
8          "type": "text",
9          "fields": {
10            "keyword": {
11              "type": "keyword"
12            }
13          }
14        },
15        "address": {
16          "type": "text",
17          "fields": {
18            "keyword": {
19              "type": "keyword"
20            }
21          }
22        },
23        "remark": {
24          "type": "text",
25          "fields": {
26            "keyword": {
27              "type": "keyword"
28            }
29          }
30        },
31        "age": {
32          "type": "integer"
33        },
34        "salary": {
35          "type": "float"
36        },
37        "birthDate": {
38          "type": "date",
39          "format": "yyyy-MM-dd"
40        },
41        "createTime": {
42          "type": "date"
43        }
44      }
45    }
46  }
47}

删除索引

删除 mydlq-user 索引。

1DELETE /mydlq-user

2、Java 代码示例

  1import lombok.extern.slf4j.Slf4j;
2import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
3import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
4import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
5import org.elasticsearch.action.support.master.AcknowledgedResponse;
6import org.elasticsearch.client.RequestOptions;
7import org.elasticsearch.client.RestHighLevelClient;
8import org.elasticsearch.common.settings.Settings;
9import org.elasticsearch.common.xcontent.XContentBuilder;
10import org.elasticsearch.common.xcontent.XContentFactory;
11import org.springframework.beans.factory.annotation.Autowired;
12import org.springframework.stereotype.Service;
13import java.io.IOException;
14
15@Slf4j
16@Service
17public class IndexService2 {
18
19    @Autowired
20    private RestHighLevelClient restHighLevelClient;
21
22    /** 23     * 创建索引 24     */
25    public void createIndex() {
26        try {
27            // 创建 Mapping
28            XContentBuilder mapping = XContentFactory.jsonBuilder()
29                .startObject()
30                    .field("dynamic", true)
31                    .startObject("properties")
32                        .startObject("name")
33                            .field("type","text")
34                            .startObject("fields")
35                                .startObject("keyword")
36                                    .field("type","keyword")
37                                .endObject()
38                            .endObject()
39                        .endObject()
40                        .startObject("address")
41                            .field("type","text")
42                            .startObject("fields")
43                                .startObject("keyword")
44                                    .field("type","keyword")
45                                .endObject()
46                            .endObject()
47                        .endObject()
48                        .startObject("remark")
49                            .field("type","text")
50                            .startObject("fields")
51                                .startObject("keyword")
52                                    .field("type","keyword")
53                                .endObject()
54                            .endObject()
55                        .endObject()
56                        .startObject("age")
57                            .field("type","integer")
58                        .endObject()
59                        .startObject("salary")
60                            .field("type","float")
61                        .endObject()
62                        .startObject("birthDate")
63                            .field("type","date")
64                            .field("format", "yyyy-MM-dd")
65                        .endObject()
66                        .startObject("createTime")
67                            .field("type","date")
68                        .endObject()
69                    .endObject()
70                .endObject();
71            // 创建索引配置信息,配置
72            Settings settings = Settings.builder()
73                    .put("index.number_of_shards", 1)
74                    .put("index.number_of_replicas", 0)
75                    .build();
76            // 新建创建索引请求对象,然后设置索引类型(ES 7.0 将不存在索引类型)和 mapping 与 index 配置
77            CreateIndexRequest request = new CreateIndexRequest("mydlq-user", settings);
78            request.mapping("doc", mapping);
79            // RestHighLevelClient 执行创建索引
80            CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
81            // 判断是否创建成功
82            boolean isCreated = createIndexResponse.isAcknowledged();
83            log.info("是否创建成功:{}", isCreated);
84        } catch (IOException e) {
85            log.error("", e);
86        }
87    }
88
89    /** 90     * 删除索引 91     */
92    public void deleteIndex() {
93        try {
94            // 新建删除索引请求对象
95            DeleteIndexRequest request = new DeleteIndexRequest("mydlq-user");
96            // 执行删除索引
97            AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
98            // 判断是否删除成功
99            boolean siDeleted = acknowledgedResponse.isAcknowledged();
100            log.info("是否删除成功:{}", siDeleted);
101        } catch (IOException e) {
102            log.error("", e);
103        }
104    }
105
106}

五、文档操作示例

1、Restful 操作示例

增加文档信息

在索引 mydlq-user 中增加一条文档信息。

 1POST /mydlq-user/doc
2{
3    "address": "北京市",
4    "age": 29,
5    "birthDate": "1990-01-10",
6    "createTime": 1579530727699,
7    "name": "张三",
8    "remark": "来自北京市的张先生",
9    "salary": 100
10}

获取文档信息

获取 mydlq-user 的索引 id=1 的文档信息。

1GET /mydlq-user/doc/1

更新文档信息

更新之前创建的 id=1 的文档信息。

 1PUT /mydlq-user/doc/1
2{
3    "address": "北京市海淀区",
4    "age": 29,
5    "birthDate": "1990-01-10",
6    "createTime": 1579530727699,
7    "name": "张三",
8    "remark": "来自北京市的张先生",
9    "salary": 100
10}

删除文档信息

删除之前创建的 id=1 的文档信息。

1DELETE /mydlq-user/doc/1

2、Java 代码示例

  1import club.mydlq.elasticsearch.model.entity.UserInfo;
2import com.alibaba.fastjson.JSON;
3import lombok.extern.slf4j.Slf4j;
4import org.elasticsearch.action.delete.DeleteRequest;
5import org.elasticsearch.action.delete.DeleteResponse;
6import org.elasticsearch.action.get.GetRequest;
7import org.elasticsearch.action.get.GetResponse;
8import org
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值