elasticsearch 搜索

一.什么是Elasticsearch
Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎,Elasticsearch和Mysql,Redis,MongoDb,Clickhouse等一样,都可以认为它是一种数据库

二.为什么要用Elasticsearch
设想一个场景:

user表有6千多万条数据,我想查询nick中包含”大帅哥“的数据:

Select nick from user where nick like '%大帅哥%'

比如,我把大帅哥写成了帅哥,写成了大帅锅,写成了dashuaige,甚至写成了dsg,大帥哥等,此时的 Mysql是无法处理的,而Elasticsearch借助分词器(后续介绍),可以简单快速查询检索。

三.Mysql和Elasticsearch概念对比
1、 MySQL 的数据库(DataBase)相当于 Index(索引),数据的逻辑集合,ES 的工作主要也是创建索引,查询索引。

2、 一个数据库里会有多个表(Table),同样的一个 Index 也会有多个 type。

3、 一个表会有多行(Row),同样的一个 Type 也会有多个 Document。

4、 Schema 指定表名,表字段,是否建立索引等,同样的 Mapping 也指定了 Type 字段的处理规则,即索引如何建立,是否分词,分词规则等。

5、MySQL 中一个row对应多个Column,同样的一个Document会有多个Fields。

6、 在 MySQL 中索引是需要手动创建的,而在 ES 一切字段皆可被索引,只要在 Mapping 在指定即可。


总结:

Mysql关系型数据库,适用于结构化数据(数据与数据之间存在强关联)的数据存储和查询和数据与数据之间的关系处理,大量数据检索需要全表查询,性能差

Elasticsearch非关系型数据库,适用于数据与数据之间相对独立的大量数据的检索查询,数据修改效率低于Mysql,不善于处理数据之间的关系

四.实际操作
通过Docker,使用es和kibana镜像,开启es服务和kibana(后续介绍)。

 
我们使用的版本号是:5.6.12

使用Kibana Dev Tool(后续介绍)操作:

索引的新建

Setting和Mapping的解释
Setting:es通过settings设置索引的基础参数,包括分词器、分片等。

PUT /baobaokanjia/
{
  "settings": {
    "number_of_shards": 1,
    "analysis": {
      "analyzer": {
        "ik_max_word_t2s": {
          "char_filter": [
            "tsconvert"
          ],
          "tokenizer": "standard"
        },
        "ik_smart_t2s": {
          "char_filter": [
            "tsconvert"
          ],
          "tokenizer": "standard"
        },
        "pinyin_analyzer": {
          "tokenizer": "my_pinyin"
        }
      },
      "char_filter": {
        "tsconvert": {
          "convert_type": "t2s",
          "type": "stconvert",
          "keep_both": "false",
          "delimiter": "#"
        }
      },
      "tokenizer": {
        "my_pinyin": {
          "lowercase": "true",
          "keep_original": "true",
          "remove_duplicated_term": "true",
          "keep_separate_first_letter": "true",
          "type": "pinyin",
          "limit_first_letter_length": "16",
          "keep_full_pinyin": "true"
        }
      }
    }
  }

解释:上述给索引baobaokanjia设置了1个分片,设置了ik分词器和拼音分词器,以及分词器的具体设置

Mapping:用来定义文档以及其字段如何被存储和索引,也就是定义字段的数据类型、字段的权重、分词器等属性

POST /baobaokanjia/test/_mapping
{
  "properties": {
    "id": {
      "type": "text"
    },
    "title": {
      "type": "keyword",
      "fields": {
        "mytsconvert": {
          "type": "text",
          "boost": 10,
          "analyzer": "ik_max_word_t2s"
        },
        "pinyin": {
          "type": "text",
          "boost": 10,
          "term_vector": "with_offsets",
          "analyzer": "pinyin_analyzer"
        }
      }
    },
    "tag": {
      "type": "text",
      "fields": {
        "mytsconvert": {
          "type": "text",
          "boost": 10,
          "analyzer": "ik_max_word_t2s"
        },
        "pinyin": {
          "type": "text",
          "boost": 10,
          "term_vector": "with_offsets",
          "analyzer": "pinyin_analyzer"
        }
      }
    }
  }

解释:上述给索引baobaokanjia 下type为test的文档设置了mapping,分别给字段id,title,tag设置了数据类型和分词器

在某个type下新增文档

查询语法的演示

上述为一个基础的简单查询,检索语法多种多样,具体场景,具体使用。参考链接:www.elastic.co/guide/cn/el…

文档的修改/删除
 
PUT和POST都可以用来文档的更新操作。需要注意,ES文档修改性能并不理想,如果数据量比较大,操作又比较频繁的情况下,update这种操作还是要慎重。


上述为文档的删除操作

索引的删除

五.ES简单原理
ES中数据查询为何如此高效,能在海量数据下达到秒级的效果呢?

1、倒排索引

①先说正向索引,使用的是一种文档到关键字的方式 document -> to -> words

②那如果将文档到关键字的结构反过来,是 word -> to -> documents

倒排索引(Inverted Index)是一种存储形式,在检索的场景中,可以实现快速的搜索需求,其由两部分构成,分别是 Term Dictionary、Posting List。在 ES 中,关键词被称为term,这一系列的 Term 组成了Term Dictionary。PostingList,倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。

举例,有三个文档(三条数据):

文档(数据)ID    文档(数据)内容
11    宝宝砍价程序开发
22    小说项目测试
33    项目开发属于开发范畴
需求:要查询包含关键词”开发“ 的所有文档(数据)

正向索引的过程:

①拿着第一个文档的ID(11),去第一条数据的内容中查找,看是否包含关键词”开发“

②拿着第二个文档的ID(22),去第二条数据的内容中查找,看是否包含关键词”开发“

③拿着第三个文档的ID(33),去第三条数据的内容中查找,看是否包含关键词”开发“

倒排索引的过程:

首先分词系统将三个文档内容切分成单词,并对每个不同的单词赋予唯一的单词编号(WordID),即:宝宝,砍价,程序,开发,小说,项目,测试,属于,范畴。得到如下的数据:

单词ID(WordID)    单词(Word)
1    宝宝
2    砍价
3    程序
4    开发
5    小说
6    项目
7    测试
8    属于
9    范畴
上述9个单词,即为9个term,它们组成的集合,称为Term Dictionary(如上概念),得到了Term Dictionary,现在需要得到倒排列表Posting List。

倒排列表格式为:(DocID;TF;)

DocID: 文档ID(每条数据的ID)

TF(term frequency): 单词在文档中出现的次数

Pos: 单词在文档中出现的位置

因为倒排索引是word -> to -> documents,按照上述格式,单词”开发“的倒排列表即为:

(11,1,<4>),(33,2,<2,4>)

解释为,”开发”在文档11中出现了1次,在11文档中的位置为4,在33文档中出现了2次,位置分别为2,4

以此类推,可以得到完整的倒排索引:

单词ID(WordID)    单词(Word)    倒排列表(DocID;TF;)
1    宝宝    (11,1,<1>)
2    砍价    (11,1,<2>)
3    程序    (11,1,<3>)
4    开发    (11,1,<4>),(33,2,<2,4>)
5    小说    (22,1,<1>)
6    项目    (22,1,<2>),(33,1,<1>)
7    测试    (22,1,<3>)
8    属于    (33,1,<3>)
9    范畴    (33,1,<5>)
再回到最开始的需求,查询包含关键词”开发“ 的所有文档,通过如上表格,很快速就能得到结果,文档11,文档33里包含关键词”开发“,比正向索引快很多。

实际场景中,海量数据下,倒排索引(反向索引)独特的数据查找方式(词典+映射表,查询速度快),加上特殊的存储结构FST(通过对词典中单词前缀和后缀的重复利用来压缩存储空间),使得他查询速度快,空间占用小,这也是ES适合海量数据检索的原理。

2. TF-IDF算法

在上述原理介绍中,倒排索引能够快速查找出大量数据,那么这些数据怎么排序呢?实际在ES中,返回结果是按相关性倒序排列的。

Elasticsearch 的相关性算法TF-IDF ,包括以下内容:

①检索词频率

检索词在对应字段出现的频率,出现频率越高,相关性也越高。字段中出现过 3 次要比只出现过 1 次的相关性高。

Eg:检索词(开发)则 : “项目开发属于开发范畴” > “项目开发属于测试范畴”

②反向文档频率

每个检索词在索引中出现的频率,频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

Eg:检索词(小说)> 检索词(开发) [小说在1个文档中出现,开发在2个文档中出现]

③字段长度准则

字段的长度是多少,长度越长,相关性越低。检索词出现在一个短的字段下要比同样的词出现在一个长的字段权重更大。

Eg:检索词(砍价)则 : “宝宝砍价” > “宝宝砍价程序开发”

在返回结果中,每个文档都有相关性评分,用一个正浮点数字段 _score 来表示 , _score 的评分越高,相关性越高。相关性越高,返回顺序越靠前。影响 _score最终值的因素有很多,手动设置权重,查询语法不同等都可以影响_score的值。


六.Mysql数据同步至ES的常用方法和思路
同步双写,这是一种最为简单的方式,在将数据写到mysql时,同时将数据写到ES,实现数据的双写。
优点:业务逻辑简单

缺点:存在双写失败丢数据风险,性能较差

异步双写,在将数据写到mysql后,用MQ方式或者定时任务方式再写入ES,实现数据的双写
优点:同步变为异步,做了部分解耦,性能较同步双写会提高

缺点:业务系统增加MQ代码,多一个MQ中间件要维护,时效性较差

基于Binlog同步, 读取mysql的binlog(后续介绍)日志,获取指定表的日志信息,将读取的信息转为MQ,编写一个MQ消费程序,不断消费MQ,每消费完一条消息,将消息写入到ES中。
优点:性能高,业务解耦,不需要关注原来系统的业务逻辑。

缺点:mysql binlog必须是ROW模式,存在MQ延时的风险

总的来说,基于Binlog 同步,也是业界比较成熟的方案,这里介绍一个组件canal,canal是阿里云开源的解析binlog组件,可用于数据同步至ES,开源成熟稳定,简单易用。


参考链接:github.com/alibaba/can…

canal可用于私有化部署mysql,es时作为一个同步工具。因为目前公司项目很多服务都是直接用的阿里云的云服务,RDS MySQL,云数据库redis版等。可直接通过阿里云DTS(Data Transmission Service),快速创建RDS MySQL到阿里云Elasticsearch的实时同步,操作更简单,快速,方便,只需要点点点即可。

参考链接:help.aliyun.com/document_de…

备注,解释下文中出现的概念:
一.Elasticsearch分词器,也叫分词插件,放在ES下plugins目录下,除了内置的一些插件外,中文常用的分词器有,IK分词器,pinyin分词器,繁体字分词器等。上述倒排索引中介绍的,将文档内容(宝宝砍价程序开发),拆分成单词(宝宝,砍价,程序,开发)就可以用IK分词器,分词器多种多样,也有不同的功能,具体的使用可在创建索引时,在setting/mapping具体设置。

二.Kibana,ELK架构中(Elasticsearch、Logstash和Kibana)中的Kibana,是一个数据分析和可视化平台,通常与Elasticsearch配合使用,用于对其中的数据进行搜索、分析,并且以统计图标的形式展示。

三.Kibana Dev Tool,是Kibana平台里一个可以对ES操作的功能,可以用DSL语法对ES可视化操作,带有语法提示功能,用Kibana Dev Tool操作ES,有点像用Phpadmin操作Mysql。

四.Binlog,MySQL的二进制日志,它记录了所有的DDL和DML语句(除select),以事件形式记录,可以用该日志来做数据恢复和数据同步。

至此,你就可以了解到:

1.Elasticsearch是什么,它和其他数据库的区别,以及它擅长做的事

2.它擅长做海量数据检索的原因和原理

3.它的一些基础操作

4.了解实际使用中的数据同步思路

配合使用,用于对其中的数据进行搜索、分析,并且以统计图标的形式展示。

三.Kibana Dev Tool,是Kibana平台里一个可以对ES操作的功能,可以用DSL语法对ES可视化操作,带有语法提示功能,用Kibana Dev Tool操作ES,有点像用Phpadmin操作Mysql。

四.Binlog,MySQL的二进制日志,它记录了所有的DDL和DML语句(除select),以事件形式记录,可以用该日志来做数据恢复和数据同步。
————————————————
版权声明:本文为CSDN博主「东方睡衣」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/web2022050903/article/details/127623642

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值