全文检索与ElasticSearch(一)——ES概述,正向索引与倒排索引,B+树,简单命令,Mapping

ElasticSearch概述

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful接口。它可以近乎实时的存储、检索数据;本身扩展性非常好,一个ES节点就可以认为是一个集群(默认支持集群),它可以扩展到上百台服务器。ES的生产环境至少在8GB以上

Lucene和ES的关系

  1. Lucene只是一个库,必须使用Java作为开发语言将他集成到应用中,使用起来十分复杂
  2. ElasticSearch也是使用Java开发并使用Lucene作为其核心来实现所有索引和搜索功能,它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,让全文搜索变得简单

ES和Mysql对比理解

MySQLElastic Search
DatabaseIndex
TableType
RowDocument
ColumnField
SchemaMapping
IndexEverything is indexed
SQLQuery DSL
SELECT* FORM table…GET http://…
UPDATE table SET…PUT http://…
  • 关系型数据库中schema定义了表,字段以及表和字段之间的关系。与之对应的,在ES中:Mapping定义索引下的Type的字段处理规则,即索引如何建立、索引类型、是否保存原始索引json文档、是否需要分词处理、如何进行分词处理等等
  • Mysql主要用途:存储数据,用来完成强一致性,保证ACID的数据,逻辑性事务性操作
  • Redis主要用途:存储数据,做缓存
  • ES主要用途:存储数据,提供全文检索

ES核心概念

  1. 索引Index:ES中的索引类似关系型数据库中的数据库,里面存放用户文档数据,因为ES是封装的Lucene,所以底层还是由Lucene的一个或者多个索引组成,数据的增删改查也是由底层的Lucene完成,ES中的分片或副本实际上就是一个Lucene索引
  2. 文档Document:文档是ES中存储数据的主体,ES中所有操作都是建立在文档的基础上的,每个文档都是由各种Field组成,每一个Field有一个名称和一个或多个值构成,文档展示给用户就是一个JSON对象
  3. 类型Type:ES中Type是一种逻辑上的概念,类似关系型数据库中的表,每个文档都属于某一种类型,如果没有定义类型会有默认值,ES每个索引可以包含多种类型。现在ES5.0之后,就不推荐使用Type了,全部叫_doc
  4. 映射Mapping:映射类似关系型数据库中的schema,用于定义field的属性,如字段类型、是否分词等,这里有一点和关系型数据库不同的是ES会在用户没有定义字段属性的情况下,自动嗅探该字段的类型进行自动识别
  5. 集群Cluster:多个ES节点工作在一起组成一个集群,ES对于集群的支持几乎是无缝的
  6. 节点Node:一个ES实例就是一个节点,说的再简单点,一台部署了ES服务器的机器就是一个节点,同时一台机器如果硬件资源允许也可以同时启动多个ES实例,ES中每个节点都和集群(如果是多个节点的集群)中的其他节点相互通信,了解多有文档存储位置并能转发用户的请求到对应的数据节点上
  7. 分片Shard:因为ES是分布式架构,类似有HDFS的存储方式,所以数据被打散存储在集群的多个节点上,一个分片实际上就是底层Lucene的一个索引,这里说分片指的是ES中的主分片,分片的方式是ES自动完成,用户可以指定分片的数量,主分片一旦指定就不能修改,因为ES打散数据的方式和索引创建时指定的主分片数量有关,后期改变会导致分片中的数据不可搜索
  8. 副本Replia:副本就是分片的一个备份,不仅能提高自身容灾,而且在请求量巨大的情况下可以分担Shard的压力,承担查询功能,副本个数可以在创建完成之后调整

索引

正向索引—MySQL索引

  • 创建mysql索引:CREATE INDEX 索引名称 ON 表明(字段名)
    添加索引后能够有效提高程序检索的效率,插入200w数据,没用索引查询时间约1.2s;加入索引后查询时间约为0.005s,数据量越大,区别越明显对于需要频繁修改的字段,不要添加索引,原因是mysql索引基于B+树(这也是添加索引查询变快的原因)
  • 聚集索引:主键就是聚集索引,且在一个表中,只能有一个聚集索引,聚集索引直接在表上进行了排序,这也就是为什么插入数据的时候id为2的比id为3的后插入但是会排在id为3的之前
  • 非聚集索引:mysql中非聚集索引无限制,排序没有在表上排序,而是在索引中排序的。通过非聚集索引查询时会先查询到聚集索引,在通过聚集索引查询数据
  • 索引的建立要花时间,就是一种排序算法
  • 普通的crud,B+树完全可以胜任,但是B+树一定要建立在高基数的列上,比如身份证号、电话号码等

B+树索引

B+树的特征:
  1. 有k个子树的中间节点包含有k-1个元素,每个元素不保存数据,只用来索引,所有数据都保存在叶子节点
  2. 所有叶子节点中包含了全部元素信息,及指向含这些元素记录的指针,且叶子节点本身依关键字的大小而自小而大顺序连接
  3. 所有中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)的元素
m阶B+树插入:
  1. 若为空树,则创建一个子结点,然后将记录插入其中,此时这个叶子结点也是根结点,插入操作结束
  2. 针对叶子类型的结点,根据key值找到叶子结点,想这个叶子结点插入记录,插入后,若当前结点key的个数小于等于m-1,则插入结束,否则这个叶子结点分裂成左右两个子结点,左叶子结点包含前m/2个记录,右叶子结点包含剩下的记录,将第m/2+1个记录进位到父结点中(父结点一定是索引类型结点),进位到父结点的key做左孩子指针指向左节点,右孩子指针指向右结点当前结点指针指向父结点,然后执行第三步
  3. 针对索引类型结点,若当前结点key的个数小于等于m-1,则插入结束;否则该索引类型分裂成两个索引结点,左索引结点包含前m/2个记录,右索引结点包含剩下的记录,将第m/2+1个记录移动到父结点中,进位到父结点的key做左孩子指针指向左节点,右孩子指针指向右结点当前结点指针指向父结点,重复执行直到插入结束
B+树的查找

B+树就是一个排序算法将一组数据排好了顺序,每个父结点右边顺序等于或高于于父结点的顺序,左边都等于或低于父结点的顺序;查找时由父结点开始一层层向子结点比较。效率比一个个比较子结点效率要高的多

正向索引

在对比如数字这样能够轻易排序的类型使用正向索引,创建对应的B+树,在查找时就可以很快的找到对应的列

倒排索引—ES索引

对于全文检索,检索字符串中的某一段字符时,就只能进行模糊查询,索引就失效了而倒排索引会先对字段进行分词,然后每个分词对应一组document的唯一标识,所有单词存储在一个B+树实现的单词字典中(字典中还存有单词和倒排列表之间的联系,倒排列表包含document的标识);查询时会将查询的内容进行分词,然后通过b+树查询找到对应分词就可以找到对应的ducument,这比mysql模糊查询的全盘查找快得多

ES的安装(docker)

  1. docker search -f stars=100 elasticsearch
    在这里插入图片描述
  2. docker pull elasticsearch:7.0.0
  3. docker images检查是否拉取成功
  4. 启动容器:docker run --name=my_es -d -p9200:9200 -e "discovery.type=single-node" docker.io/elasticsearch:7.0.0
  5. 配置防火墙:firewall-cmd --zone=public --add-port=9200/tcp --permanentfirewall-cmd --reload
  6. 浏览器敲地址查看是否正常访问
    在这里插入图片描述

Kibana

kibana是为ES设计的开源分析和可视化平台,可以使用kibana来搜索,查看存储在ES索引中的数据并与之交互
kibana的安装过程和es相同,启动是配置环境变量:docker run --name=kibana -e ELASTICSEARCH_HOSTS=es的地址与端口 -e SERVER_PORT=5601 -e SERVER_HOST=0.0.0.0 -p 5601:5601 -d kibana

ES命令

_cat命令(查看集群状态)

  1. /_cat/allocation:查看单节点的shard分配整体情况
  2. /_cat/shards:查看各shard的详细情况
  3. /_cat/shards/{index}:查看指定分片的详细情况
  4. /_cat/master:查看master节点的信息
  5. /_cat/nodes:查看所有节点的信息
  6. /_cat/indices:查看集群中所有index的详细信息
  7. /_cat/indices/{index}:查看集群中指定index的详细信息
  8. /_cat/segments:查看各index的segment的详细信息,包括segment名,所属shard,内存(磁盘)占用大小,是否刷盘
  9. /_cat/segments/{index}:查看指定index的segment的详细信息,包括segment名,所属shard,内存(磁盘)占用大小,是否刷盘
  10. /_cat/count:查看当前集群的document数量
  11. /_cat/count/{index}:查看指定索引的document数量
  12. /_cat/recovery:查看集群内每个shard的recovery的过程,调整replica
  13. /_cat/recovery/{index}:查看指定索引shard的recovery过程
  14. /_cart/health/:查看集群当前健康状态,红、黄、绿
  15. /_cat/pending_tasks/:查看当前集群的pending task(等待任务)
  16. /_cat/aliases/:查看集群中所有索引的alias(别名)信息
  17. /_cat/aliases/{alias}:查看指定索引的alias信息
  18. /_cat/thread_pool:查看集群各节点内部不同类型的threadpool的统计信息
  19. /_cat/plugins:查看集群各个节点的插件信息
  20. /_cat/fielddata:查看集群各个节点的fielddata内存使用情况
  21. /_cat/fielddata/{fields}:查看指定field的内存使用情况,里面传field属性对应的值
  22. /_cat/nodeattrs:查看单节点的自定义属性
  23. /_cat/repositores:输出集群中注册快照存储库
  24. /_cat/templates:输出当前正在存在的模板信息

简单的增删改查

增加

  1. INDEX
PUT 索引名/类型名(统一使用_doc)/id
{
	json对
}
  1. CREATE
PUT 索引名/create/id
{
	json对
}
POST 索引名/create (不指定id自动生成)
{
	json对
}

两种操作的区别

  • create操作如果id已经存在,会失败
  • index操作,如果id不存在,会创建新的文档,否则先删除现有文档再创建新的文档,版本会增加

查询

  1. GET /_search{}:空查询,将返回所有索引库中所有文档信息
  2. 基本查询
    GET 索引名/_doc/_search:查询索引下的全部文档
    GET 索引名/_doc/id:通过id查询文档
    GET 索引名:查看索引信息
    GET 索引名/_doc/_search?q=key:value:简单条件查询
  3. match_all查询
    简单匹配所有文档,在没有指定查询方式时,它是默认的查询;_source表示查询的字段,没有表示查询所有字段;from和size用作分页查询;sort表示按照字段进行排序,asc正序,desc倒序
GET 索引名/_search
{
	"_source":["字段1","字段2"],
	"query":{
		"match_all":{
		
		}
	},
	"from":0,
	"size":2,
	"sort":{
		"字段":{
			"order":"asc/desc"
		}
	}
}

更新

ES的更新数据可以添加新的字段,这是mysql所不能的

  1. PUT更新
PUT 索引名/_doc/id
{
	json对
}

删除原有的文档并创建新的文档,版本增加
2. POST更新

PUT 索引名/_doc/id
{
	json对
}

在原有的文档上更新字段,版本增加

PUT和POST的区别

  1. 更新:PUT会将新的json值完全替换掉旧的;而POST方式只会更新相同的字段的值,其他数据不会改变,新提交的字段若不存在则增加
  2. PUT和DELETE操作是幂等的,所谓幂等是指不管进行多少次操作,结果都一样,比如用PUT修改一个文档,然后再做同样的操作,每次操作后结果并没有什么不同,DELETE也是一样
  3. POST操作不是幂等的,比如常见的POST重复加载问题,多次发出同样的POST请求后,其结果是创建了若干的资源
  4. 创建操作可以使用POST,也可以使用PUT,区别在于POST作用在一个集合资源之上的,而PUT操作时作用在一个具体资源之上的;即POST是指在_doc基础上创建一个文档,而PUT是指在具体文档的基础上创建它

删除

  1. DELETE 索引名:删除索引
  2. DELETE 索引名/_doc/id:通过id删除文档

Mapping

概述

ES的Mapping,定义了索引的结构,类似于关系型树库的schema。ES的Setting中定义分片和副本数以及搜索的最关键组件,即Analyzer分词器。

Mapping主要包含以下内容:
1. 定义索引中字段的名称
2. 定义字段的数据类型
3. 可对字段设置倒排索引的相关配置,如是否需要分词,使用什么分词器

从7.x开始,一个Mapping只属于一个索引的type,默认为_doc
每个文档属于一个type
一个type只有一个Mapping定义
从7.x开始,不需要在Mapping中指定type信息,默认type为_doc

Mapping中的字符串类型

  1. text:类型适用于需要被全文检索的字段,text类型会被Lucene分词器处理为一个个单词,并使用Lucene倒排索引存储,text字段不能被用于排序,如果需要使用该类型的字段只需要定义映射时指定JSON中对应字段的type为text
  2. keyword:关键字的整体,不会被分词,适合简短,结构化字符串,如主机名、姓名、商品名称,可以用于过滤、排序、联合检索、也可以用于精确查询

Mapping字段类型的指定

Mapping中的字段类型会自动识别,如果输入的JSON是字符串而且格式为日期格式,ES会自动设置成Date类型;当输入的字符串是数字的时候,ES默认也会当成字符串来处理。

如果想要指定字段类型,需要在创建索引时对某个字段的类型进行指定,这样新增的该字段数据就是该类型的;对于已经存在的字段,是不支持修改的,如果希望更改已存在的字段的类型,必须重建索引

指定类型

PUT 索引名
{
  "mappings": {
    "properties": {
      "字段名":{
        "type":"类型"
      }
    }
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值