ES DSL、特性、索引、基概、进阶

elasticsearch

1 特点

1.1 天然分片,天然集群

实则es是把这个数据分为多个碎片分布式的放在各个节点上,随着数据的增加会将其增加节点数,将多个分片放在多个节点上,以此达到负载均衡的目的。

在实际运算过程中,每个查询任务提交到某个节点,该节点必须负责将数据进行整理聚合,再返回给客户端 ===> Map计算,在一个固定的节点上进行的reduces得到最终结果向客户端返回

1.2 天然索引

ES所有数据都是默认进行索引的,而作为传统数据库的mysql是默认没有索引的,因为es数据很多,所以在数据处理上我们可以压缩,但是压缩是牺牲cpu的,因而消耗的资源就得很高

注意:如果既要写索引又要压缩那就可以异步,可以先将数据放在内存再写入磁盘,如果中间有丢失那就只能丢失

ES使用的是倒排索引和mysql的B+Tree索引是不同的

1.3 lucene倒排索引结构

实际上的倒排索引分为三层:

第一层叫做:Term Index(词条、分条索引):主要功能是很方便快速定位你要查找语句中的词语,因为是二叉树(折半查找)很快的定位,查找到词语之后又会指向主键列表,主键列表就是对应的位置(具体的数据)

lucene相当于就是es的‘引擎’

2 基概

名词解释
cluster整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。
node集群中的一个节点,一般只一个进程就是一个node
shard分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。(7.0默认改为1片)
index相当于rdbms的database(5.x), 对于用户来说是一个逻辑数据库,虽然物理上会被分多个shard存放,也可能存放在多个node中。 6.x 7.x index相当于table
type类似于rdbms的table,但是与其说像table,其实更像面向对象中的class , 同一Json的格式的数据集合。(6.x只允许建一个,7.0被废弃,造成index实际相当于table级)
document类似于rdbms的 row、面向对象里的object
field相当于字段、属性

3 状态介绍

3.1 状态1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B0JhyMGP-1618488298435)(../../AppData/Roaming/Typora/typora-user-images/image-20210415142232463.png)]

GET _cat/indices?v

?v:加上表头方便知道具体含义

green:至少有一个分布式副本

yellow:可能没有副本,但是主数据完整

red:主数据不完整

3.2 状态2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4v0FaHEq-1618488298437)(../../AppData/Roaming/Typora/typora-user-images/image-20210415143537833.png)]

GET /_cat/shards/customer001?v

p:主片;r:副本

这里拿的是主键(这里的主键为1,可以字符也可以数字)取余产生的结果

4 es中的DSL

4.1 数据结构

es中保存的数据结构

public class  Movie {
	 String id;
    String name;
    Double doubanScore;
    List<Actor> actorList;
}

public class Actor{
String id;
String name;
}

//上文两个对象放在传统数据库中会被拆分成两张表,但是在ES中会用json数据来表示一个document
{
 "id":"1",
 "name":"operation red sea",
 "doubanScore":"8.5",
 "actorList":[  
{"id":"1","name":"zhangyi"},
{"id":"2","name":"haiqing"},
{"id":"3","name":"zhanghanyu"}
] 
}

4.2 增加操作

增加分为两种方式:

put:幂等性,指定id,同一数据的多次执行对整体数据库无影响,不会增加,只会去替换最新的数据

post:非幂等性,同一数据的多次执行对整体的数据有影响,会去增加一个新 id,不会替换原来数据会新建一个数据

4.3 更新操作

用post指定具体修改处,不用put的原因是因为put会将原来的所有信息进行替换

4.4 删除索引

DELETE /movie_index

注意:Es不会去删除或者修改数据,而是增加版本号

4.5 查询操作

// match分词匹配,必须使用分词 text字段
GET movie_index/_search
{
  "query": {
    "match": {
      "name": "operator red sea"
    }
  }
}

// 查询某个具体值
GET movie_index/_search
{
  "query": {
    "match": {
      "actorList.name": "zhang han yu"
    }
  }
}

// 过滤查询
// term 值等匹配 必须用keyword类型字段
// term 中的词是不会被分词的,但es默认会将数据中的词进行分词所以除非是分词内的,否则term中查不到该分词
GET movie_index/_search
{
  "query": {
    "term": {
      "actorList.name.keyword": "zhang han yu"
    }
  }
}

// text是专用的分词字段 keyword是不分词字段


// 短语匹配 类似于 like '%xxxx%'
GET movie_index/_search
{
  "query": {
    "match_phrase": {
      "actorList.name": "zhang han yu"
    }
  }
}

// fuzzy查询,模糊匹配(容错匹配)
GET movie_index/_search
{
  "query": {
    "fuzzy": {
      "name": "rad"
    }
  }
}
// 混合查询方式 1、先匹配,再过滤 2、同时匹配加过滤

//1.先匹配,再过滤
GET movie_index/_search
{
  "query": {
    "match": {
      "name": "red"
    }
  },
  "post_filter": {
    "term": {
      "actorList.id.keyword": "zhang han yu"
    }
  }
}

//2.同时匹配加过滤
GET movie_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "red"
          }
        }
      ],
      "filter": {
          "term": {
            "actorList.id.keyword": "zhang han yu"
          }
         }
      }
    }
}
// 范围过滤
GET movie_index/_search
{
  "query": {
    "range": {
      "doubanScore": {
        "gte": 6,
        "lte": 9
      }
    }
  }
}

4.6 分页查询

// 分页查询,类似于limit
// from = (pageNo-1)*size
// 指定的查询字段"_source":
// 高亮highlight
GET movie_index/_search
{
  "query": {
    "match": {
      "name": "red"
    }
  },
  "highlight": {
    "fields": {
      "name": "name": {"pre_tags": "<span color='red'>","post_tags": "</span>"}
    }
  },
  "_source": ["name","doubanScore"], 
  "from": 0,
  "size": 20
}

4.7 聚合

// 聚合
// 取出每个演员共参演了多少部电影
// select actorList.name,count(*) from movie group by actorList.name
// sum avg min max
GET movie_index/_search
{
  "aggs": {
    "groupbyactorName": {
      "terms": {
        "field": "actorList.name.keyword",
        "size": 10
      }
    }
  }
}

// 每个演员参演电影的平均分是多少,并按评分排序
GET movie_index/_search
{
  "aggs": {
    "groupbyactorName": {
      "terms": {
        "field": "actorList.name.keyword",
        "order": {
          "avg_score": "asc"
        }, 
        "size": 10000
      },
      "aggs": {
        "avg_score": {
          "avg": {
            "field": "doubanScore"
          }
        }
      }
    }
  }
}

5 中文分词

人为指定分词可以用nginx

先写es插件配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRBvj7sg-1618798654743)(../../AppData/Roaming/Typora/typora-user-images/image-20210416175941088.png)]

修改nginx中文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-35ZswjQP-1618798654744)(../../AppData/Roaming/Typora/typora-user-images/image-20210416180132675.png)]

修改nginx中跳转配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tmo8xxFI-1618798654745)(../../AppData/Roaming/Typora/typora-user-images/image-20210416180344701.png)]

重启es即可

6 mapping

6.1 查看mapping

GET movie_index/_mapping/movie

6.2 建立mapping模板

PUT movie_chn
{
  "mappings": {
    "movie":{
      "properties": {
        "id":{
          "type": "long"
        },
        "name":{
          "type": "text"
          , "analyzer": "ik_smart"
        },
        "doubanScore":{
          "type": "double"
        },
        "actorList":{
          "properties": {
            "id":{
              "type":"long"
            },
            "name":{
              "type":"keyword"
            }
          }
        }
      }
    }
  }
}

7 索引别名

在本质上其实和视图很像

为已存在的索引加别名

POST  _aliases
{
    "actions": [
        { "add":    { "index": "movie_chn_xxxx", "alias": "movie_chn_2020-query" }}
    ]
}

加过滤条件的别名(缩小查找的范围)

POST  _aliases
{
    "actions": [
        { "add":    
{ "index": "movie_chn_xxxx", 
"alias": "movie_chn0919-query-zhhy",
            "filter": {
                "term": {  "actorList.id": "3"
                 }
               }
 }
}
    ]
}

删除某个索引别名

POST  _aliases
{
    "actions": [
        { "remove":    { "index": "movie_chn_xxxx", "alias": "movie_chn_2020-query" }}
    ]
}

某个别名的无缝切换

这里其实可以看到他其实就是别名所指数据更新的操作,这里面类似于原子性,要么全部成功,要么全部失败

POST /_aliases
{
    "actions": [
        { "remove": { "index": "movie_chn_xxxx", "alias": "movie_chn_2020-query" }},
        { "add":    { "index": "movie_chn_yyyy", "alias": "movie_chn_2020-query" }}
    ]
}

查询别名列表

GET  _cat/aliases?v

8 索引模板

二 进阶

1 整体架构

一个运行中的 Elasticsearch 实例称为一个节点,而集群是由一个或者多个拥有相同cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。当一个节点被选举成为主节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。作为用户,我们可以将请求发送到集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的

2 读写流程

读流程

整体的框架其实就是围绕着读流程而来的,当客户端的请求过来的时候,首先会去交给协调节点,协调节点再去查看哪个节点上的负载均衡过少便于操作,就将请求交给该节点,该节点再将请求的结果返回给客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9LV0In0o-1618798654747)(../../AppData/Roaming/Typora/typora-user-images/image-20210417001754753.png)]

写流程

相对比读流程而言,写流程要复杂点,首先还是通过协调节点的负载均衡机制将请求转移合适节点,但此时主的分片是需要将数据进行保存的并且将数据分发给各个节点,然后副本->主分片->客户端逐级反馈

3 分片原理

倒排索引

传统的手段是通过模糊查询进行匹配数据,而倒排索引指的就是通过对每行数据进行有意义的分词绑定索引的操作,倒排索引通过分词策略形成文字->单词->文章的映射关系,这种映射关系和词典顺序称为倒排索引

这里的分词会有专门的分词器,主要取决于要处理的数据,分词分为两种ik_max_word(细粒度)ik_smart(粗粒度)

词条:索引中最小的存储和查询单元

词典:字典,词条的集合,一般基层是b+tree、hashmap

倒排表:关键词出现的位置,出现的频率,这里的每行记录称为倒排项

倒排索引的搜索过程:搜索的时候查询单词的词典,看单词在不在词典当中,如果不在结束,如果在看单词在倒排列表中的指针,通过倒排列表拿到文档id列表,通过文档列表拿到数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dNX2zqcj-1618798654748)(../../AppData/Roaming/Typora/typora-user-images/image-20210417003941720.png)]

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

友培

数据皆开源!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值