【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战

四、ElasticSearch进阶

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/getting-started-search.html

1.ES中的检索方式

在ElasticSearch中支持两种检索方式

  1. 通过使用REST request URL 发送检索参数(uri+检索参数)
  2. 通过使用 REST request body 来发送检索参数 (uri+请求体)

第一种方式

GET bank/_search # 检索bank下的所有信息,包括 type 和 docs

GET bank/_search?q=*&sort=account_number:asc

响应结果信息

信息 描述
took ElasticSearch执行搜索的时间(毫秒)
time_out 搜索是否超时
_shards 有多少个分片被搜索了,统计成功/失败的搜索分片
hits 搜索结果
hits.total 搜索结果统计
hits.hits 实际的搜索结果数组(默认为前10条文档)
sort 结果的排序key,没有就按照score排序
score和max_score 相关性得分和最高分(全文检索使用)

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第1张图片

第二种方式

通过使用 REST request body 来反射检索参数 (uri+请求体)

GET bank/_search

{
   "query":{
       "match_all":{}
    },
    "sort":[
       {
           "account_number":"desc"  
       }
   ]
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第2张图片

2.Query DSL

2.1 基本语法

  ElasticSearch提供了一个可以执行的JSON风格的DSL(domain-specific language 领域特定语言),这个被称为Query DSL,该查询语言非常全面,并且刚开始的时候感觉有点复杂,真正学好它的方法就是从一些基础案例开始的。

完整的语法结构

{
   QUERY_NAME:{
      ARGUMENT:VALUE,
      ARGUMENT:VALUE,...
   }
}

如果是针对某个字段,那么它的结构为

{
    QUERY_NAME:{
        FIELD_NAME:{
            ARGUMENT:VALUE,
            ARGUMENT:VALUE,...
        }
    }
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第3张图片

2.2 match

  上面我们用到来的match_all是匹配所有的数据,而我们现在要讲的match是条件匹配

如果对应的字段是基本类型(非字符串类型),则是精确匹配。

GET bank/_search
{
   "query":{
       "match":{
          "account_number":20
      }
   }
}

match返回的是 account_number:20的记录

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第4张图片

如果对应的字段是字符串类型,则是全文检索

GET bank/_search
{
   "query":{
       "match":{
          "address":"mill"
      }
   }
}

match返回的就是address中包含mill字符串的记录

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第5张图片

2.3 match_phrase

将需要匹配的值当成一个整体单词(不分词)进行检索,短语匹配

GET bank/_search
{
   "query":{
       "match_phrase":{
          "address":"mill road"
      }
   }
}

查询出address中包含 mill road的所有记录,并给出相关性得分

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第6张图片

2.4 multi_match[多字段匹配]

GET bank/_search
{
   "query":{
       "multi_match":{
          "query":"mill road",
          "fields":["address","state"]
      }
   }
}

查询出state或者address中包含 mill road的记录

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第7张图片

2.5 bool[复合查询]

布尔查询又叫组合查询,bool用来实现复合查询,

bool把各种其它查询通过 must(与)、must_not(非)、should(或)的方式进行组合

复合语句可以合并任何其他查询语句,包括复合语句也可以合并,了解这一点很重要,这意味着,复合语句之间可以相互嵌套,可以表达非常复杂的逻辑。

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第8张图片

2.6 filter[结果过滤]

  并不是所有的查询都需要产生分数,特别是那些仅用于"filtering"的文档,为了不计算分数,ElasticSearch会自动检查场景并且优化查询的执行。

GET /bank/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第9张图片

2.7 term

  和match一样,匹配某个属性的值,全文检索字段用match,其他非text字段匹配用term

GET bank/_search
{
   "query":{
       "term":{
          "account_number":20
      }
   }
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第10张图片

检索关键字 描述
term 非text使用
match 在text中我们实现全文检索-分词
match keyword 在属性字段后加.keyword 实现精确查询-不分词
match_phrase 短语查询,不分词,模糊查询

3.聚合(aggregations)

聚合可以让我们极其方便的实现对数据的统计、分析。例如:

  • 什么品牌的手机最受欢迎?
  • 这些手机的平均价格、最高价格、最低价格?
  • 这些手机每月的销售情况如何?

实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现实时搜索效果。

语法规则

"aggregations" : {
    "" : {
        "" : {
            <aggregation_body>
        }
        [,"meta" : {  [<meta_data_body>] } ]?
        [,"aggregations" : { [<sub_aggregation>]+ } ]?
    }
    [,"" : { ... } ]*
}

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-aggregations.html

3.1 基本概念

Elasticsearch中的聚合,包含多种类型,最常用的两种,一个叫 ,一个叫 度量

桶(bucket)

桶的作用,是按照某种方式对数据进行分组,每一组数据在ES中称为一个 ,例如我们根据国籍对人划分,可以得到 中国桶英国桶日本桶……或者我们按照年龄段对人进行划分:010,1020,2030,3040等。

Elasticsearch中提供的划分桶的方式有很多:

  • Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
  • Histogram Aggregation:根据数值阶梯分组,与日期类似
  • Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
  • Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
  • ……

bucket aggregations 只负责对数据进行分组,并不进行计算,因此往往bucket中往往会嵌套另一种聚合:metrics aggregations即度量

度量(metrics)

分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在ES中称为 度量

比较常用的一些度量聚合方式:

  • Avg Aggregation:求平均值
  • Max Aggregation:求最大值
  • Min Aggregation:求最小值
  • Percentiles Aggregation:求百分比
  • Stats Aggregation:同时返回avg、max、min、sum、count等
  • Sum Aggregation:求和
  • Top hits Aggregation:求前几
  • Value Count Aggregation:求总数
  • ……

3.2 案例讲解

案例1:搜索address中包含mill的所有人的年龄分布以及平均年龄

GET /bank/_search
{
  "query": {
    "match": {
      "address": "mill"
    }
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 10
      }
    },
    "ageAvg":{
      "avg": {
        "field": "age"
      }
    }
  },"size": 0 
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第11张图片

案例2:按照年龄聚合,并且请求这些年龄段的这些人的平均薪资

GET /bank/_search
{
  "query": {"match_all": {}},
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 50
      },"aggs": {
        "balanceAvg": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  },"size": 0
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第12张图片

案例3:查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资。

GET /bank/_search
{
  "query": {"match_all": {}}
  ,"aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 50
      },
      "aggs": {
        "genderAgg": {
          "terms": {
            "field": "gender.keyword",
            "size": 10
          },"aggs": {
            "balanceAvg": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
        ,"ageBalanceAvg":{
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
  ,"size": 0
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第13张图片

4.映射配置(_mapping)

查看索引库中所有的属性的_mapping

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第14张图片

4.1 ElasticSearch7-去掉type概念:

  关系型数据库中两个数据表示是独立的,即使他们里面有相同名称的列也不影响使用,但ES中不是这样的。elasticsearch是基于Lucene开发的搜索引擎,而ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。

  两个不同type下的两个user_name,在ES同一个索引下其实被认为是同一个filed,你必须在两个不同的type中定义相同的filed映射。否则,不同type中的相同字段名称就会在处理中出现冲突的情况,导致Lucene处理效率下降。

  去掉type就是为了提高ES处理数据的效率。

Elasticsearch 7.x

URL中的type参数为可选。比如,索引一个文档不再要求提供文档类型。

Elasticsearch 8.x

不再支持URL中的type参数。

解决:将索引从多类型迁移到单类型,每种类型文档一个独立索引

4.2 什么是映射?

  映射是定义文档的过程,文档包含哪些字段,这些字段是否保存,是否索引,是否分词等

4.3 创建映射字段

PUT /索引库名/_mapping/类型名称
{
  "properties": {
    "字段名": {
      "type": "类型",
      "index": true"store": true"analyzer": "分词器"
    }
  }
}

类型名称:就是前面将的type的概念,类似于数据库中的不同表

字段名:类似于列名,properties下可以指定许多字段。

每个字段可以有很多属性。例如:

  • type:类型,可以是text、long、short、date、integer、object等
  • index:是否索引,默认为true
  • store:是否存储,默认为false
  • analyzer:分词器,这里使用ik分词器:ik_max_word或者ik_smart

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第15张图片

4.4 新增映射字段

  如果我们创建完成索引的映射关系后,又要添加新的字段的映射,这时怎么办?第一个就是先删除索引,然后调整后再新建索引映射,还有一个方式就在已有的基础上新增。

PUT /my_index/_mapping
{
  "properties":{
    "employee-id":{
      "type":"keyword"
      ,"index":false
    }
  }
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第16张图片

4.5 更新映射

  对于存在的映射字段,我们不能更新,更新必须创建新的索引进行数据迁移

4.6 数据迁移

先创建出正确的索引,然后使用如下的方式来进行数据的迁移

POST_reindex [固定写法]
{
“source”:{
“index”:“twitter”
},
“dest”:{
“index”:“new_twitter”
}
}

老的数据有type的情况

POST_reindex [固定写法]
{
“source”:{
“index”:“twitter”,
“type”:“account”
},
“dest”:{
“index”:“new_twitter”
}
}

案例:新创建了索引,并指定了映射属性【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第17张图片

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第18张图片

5.分词

  所谓的分词就是通过tokenizer(分词器)将一个字符串拆分为多个独立的tokens(词元-独立的单词),然后输出为tokens流的过程。

例如"my name is HanMeiMei"这样一个字符串就会被默认的分词器拆分为[my,name,is HanMeiMei].ElasticSearch中提供了很多默认的分词器,我们可以来演示看看效果

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第19张图片

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第20张图片

但是在ElasticSearch中提供的分词器对中文的分词效果都不好。

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第21张图片

所以这时我们就需要安装特定的分词器 IK

1) 安装ik分词器

https://github.com/medcl/elasticsearch-analysis-ik 下载对应的版本,然后解压缩到plugins目录中

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第22张图片

然后检查是否安装成功:进入容器 通过如下命令来检测

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第23张图片

检查下载的文件是否完整,如果不完整就重新下载。

image.png

插件安装OK后我们重新启动ElasticSearch服务

2) ik分词演示

ik_smart分词

# 通过ik分词器来分词
POST /_analyze
{
  "analyzer": "ik_smart"
  ,"text": "我是中国人,我热爱我的祖国"
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第24张图片

ik_max_word

POST /_analyze
{
  "analyzer": "ik_max_word"
  ,"text": "我是中国人,我热爱我的祖国"
}

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第25张图片

通过ik分词器的使用我们发现:如果使用ElasticSearch中默认提供的分词器是不支持中文分词的,也就是我们在定义一个索引的使用不能使用默认的mapping,而是要手动的来建立对应的mapping,在mapping我们需要选择对应的分词器。

3) 自定义词库

虚拟机扩容

安装的软件越来越多,虚拟机的空间有限,这时我们可以关闭虚拟机后扩容

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第26张图片

ElasticSearch中原来分配的空间比较小,虚拟机空间增大后我们可以调整ElasticSearch的空间。

调整ElasticSearch的虚拟机内存,我们没办法直接修改,需要先删除原来的容器,然后创建新的容器。

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第27张图片

调整JVM参数后重新启动容器:

docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \-e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" -v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins -d elasticsearch:7.4.2

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第28张图片

Nginx安装

先安装一个简单的Nginx实例,来获取对应的配置信息

拉取Nginx的镜像

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第29张图片

启动Nginx服务

docker run -d -p 80:80 --name nginx nginx:1.10

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第30张图片

把容器中的配置文件拷贝到/mydata/nginx目录中

docker container cp nginx:/etc/nginx .

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第31张图片

有了这个对应的配置文件夹后我们就可以删除掉之前的Nginx服务了

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第32张图片

然后创建新的Nginx服务

docker run -d -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
nginx:1.10

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第33张图片

测试访问:

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第34张图片

实现自定义词库

我们需要在Nginx中创建对应的词库文件

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第35张图片

然后我们在ik分词器的插件的配置文件中修改远程词库的地址

/mydata/elasticsearch/plugins/ik/config

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第36张图片

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第37张图片

然后保存文件重启ElasticSearch服务即可

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第38张图片

然后在Kibana中检索测试即可

【业务功能篇82】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-进阶实战_第39张图片

你可能感兴趣的:(Spring,boot,Java,Spring,cloud,微服务,spring,cloud,elasticsearch,kibana)