Elasticsearch - 全文检索服务器

一、Elasticsearch 简介

Elasticsearch 是一个基于 Lucene 的全文检索服务器,提供了基于 RESTful web接口的分布式全文搜索引擎。

总结

  1. Elasticsearch是一个基于 Lucene 的分布式全文检索服务器;
  2. Elasticsearch 对 Lucene 进行了封装,隐藏了 Lucene 的复杂性,对外提供 RESTful 风格的接口来进行索引和搜索;

二、Elasticsearch 工作原理

2.1 索引结构

在这里插入图片描述
右侧蓝色部分是原始文件,左边是文件的逻辑结构。Elasticsearch 根据一定的策略从原始文档中提取出一系列的关键字(field)保存在一个文档(document)中,用这个document文档来描述原始文件,然后从所有的document文档中提取出不重复的 field 作为 分词(trem)保存在分词列表(index)中。
分词列表特点

  1. 分词列表中所有的分词(trem)是不重复的;
  2. 分词列表中不包括“的、地、啊、呀”等连词或语气词;
  3. 分词列表中不包括一些通常不会作为搜索关键字的内容作为分词,如:资源的URL等;
    总结:分词列表中的分词是不重复的,分词列表中的分词都是可能作为搜索关键字的内容;

2.2 倒排索引

正排索引:将搜索内容作为关键字,在一系列的原始文件中,进行精确或模糊匹配,将包含关键字的原始文件作为目标文件(文档 --> 关键字);
倒排索引:从搜索内容中提取若干个分词,通过分词检索 document 文档,将和搜索内容所包含分词关联性最强的document文档对应的原始文件作为目标文件。(关键字 --> 文档)

三、Elasticsearch中数据存储的结构及简单入门

Elasticsearch中数据的存储结构和关系型数据库类似,可以类比记忆:

ElasticsearchMysql(关系型数据库)
index(索引库)database(数据库)
type(类型)table(表)
document(文档)row(记录,一行数据)
field(域)column(字段)

注意:ES 6.0 之前的版本中 type(类型)相当于关系型数据库的 table(表),6.0 版本之后 type 概念被弱化,并且ES官方打算在 7.0 版本废除 type 的概念。

3.1 index管理

1、创建index索引库
语法:PUT /index_name,如:

PUT /java06
{
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 1
  }
}

number_of_shards:当索引库中数据量太大,一台ES存放不下,会将索引库拆分成多片分别存储在不同的节点中,number_of_shards 用来指定节点数量。
number_of_replicas:每个节点只有一台,一个节点挂掉整个索引库都会挂掉,为了提高系统的容错性,可以给每个节点设置备份机,number_of_replicas 用来指定每个节点的备份数量。如果只有一台机器,备份数量必须为0,如果机器挂掉了,主片和备份都会挂掉,备份就没有意义了;
2、修改index
注意:索引库(index)一旦创建,primary shard 不可修改,只能修改 replica shard 数量。
语法:PUT /index_name/_settings,如:

PUT /java06/_settings
{
  "number_of_replicas" : 1
}

为什么 primary shard 不可修改?
索引库中添加数据(document)时,会根据数据的 id 获取哈希值 hash(id),然后对主片个数(primary shard)求余(shard = hash(id) %number_of_primary_shards)来确定数据存放到那个分片中,一旦修改,会造成索引库中数据紊乱。
3、删除index
语法:DELETE /index_name,如:

DELETE /java06 //删除单个
DELETE /[index_name1, index_name2] //删除多个

3.2 mapping管理

创建映射的过程类似关系型数据库中建表的过程,确定 type 中有哪些 field ,分别是什么类型。
1、创建mapping
语法:POST /index_name/type_name/_mapping,如:

POST /java06/course/_mapping
{
  "properties": {
     "name": {
        "type": "text"
     },
     "description": {
        "type": "text"
     },
     "studymodel": {
        "type": "keyword"
     }
  }
}

2、查询mapping
查询所有索引的映射:

GET /java06/course/_mapping

3、更新mapping
映射创建成功后,可以添加新的映射,不能更改已有映射。

4、删除mapping
通过删除索引来删除映射。

3.3 document管理

1、创建document
语法:POST /index_name/type_name/id,如:

POST /java06/course/1
{
  "name":"python从入门到放弃",
  "description":"人生苦短,我用Python",
  "studymodel":"201002"
}

POST /java06/course
{
  "name":".net从入门到放弃",
  "description":".net程序员谁都不服",
  "studymodel":"201003"
}

创建document时如果不指定id,ES也会自动生成,但生成的id可读性较差,建议指定id。
2、修改document
语法:PUT/index_name/type_name/id,如:

PUT /java06/course/2
{
  "name":"php从入门到放弃",
  "description":"php是世界上最好的语言",
  "studymodel":"201001"
}

如果修改的id对应的文档不存在,会自动创建文档document。
结果:

{
  "_index": "test_index", 新增的 document 在什么 index 中,
  "_type": "my_type", 新增的 document 在 index 中的哪一个 type 中。
  "_id": "1", 指定的 id 是多少
  "_version": 1, document 的版本是多少,版本从 1 开始递增,每次写操作都会+1
  "result": "created", 本次操作的结果,created 创建,updated 修改,deleted 删除
  "_shards": { 分片信息
      "total": 2, 分片数量只提示 primary shard
      "successful": 1, 数据 document 一定只存放在 index 中的某一个 primary shard 中
      "failed": 0
  },
  "_seq_no": 0, 
  "_primary_term": 1
}

3、查询document
语法:GET /index_name/type_name/id

GET /java06/course/1

4、删除Document
语法:DELETE /index_name/type_name/id

DELETE /java06/course/3

结果:

{
  "_index": "java06",
  "_type": "course",
  "_id": "2",
  "_version": 2,
  "result": "deleted",
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 3,
  "_primary_term": 1
}

ES 中执行删除操作时,ES先标记Document为deleted状态,而不是直接物理删除。当ES 存储空间不足或工作空闲时,才会执行物理删除操作,标记为deleted状态的数据不会被查询搜索到(ES 中删除 index ,也是标记。后续才会执行物理删除。所有的标记动作都是为了NRT(近实时)实现)

四、field详细介绍

4.1 field 的属性介绍

1、type
type 属性用来指定 field 的类型。
field 常用类型:
字符串:text、keyword;
数字:integer、long、float、double;
text类型的字段需要通过analyzer 属性指定分词模式。
keyword类型的字段往索引目录写时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。

2、analyzer
analyzer 属性用来指定分词模式。
可以在创建索引和搜索的时候指定不同的分词器。建议在创建索引时使用 ik_max_word 分词器进行细粒度的分词,搜索时使用 ik_smart 分词器进行粗粒度的分词。

	"name": {
    	"type": "text",
        "analyzer":"ik_max_word",#生成索引目录时
        "search_analyzer":"ik_smart"#检索时
	}

分词器
指定分词模式就是选择分词器。由于Lucene 是由外国人开发,Lucene 自带的分词器对中文的分词效果很不好,比如自带的三种分词器:

StandardAnalyzer: 单字分词:就是按照中文一个字一个字地进行分词。如:“我爱中国”,效果:“我”、“爱”、“中”、“国”。

CJKAnalyzer: 二分法分词:按两个字进行切分。如:“我是中国人”,效果:“我是”、“是中”、“中国”、“国人”。

SmartChineseAnalyzer: 对中文支持较好,但扩展性差,扩展词库和禁用词库等不好处理。

因此,我们通常使用由第三方的分词器:如:IK分词器

IK分词器有两种分词模式:ik_max_word和ik_smart模式。

  1. ik_max_word:会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民大会堂、人民、共和国、大会堂、大会、会堂等词语。
  2. ik_smart:会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。

IK分词器支持自定义词库,IK分词器安装目录里config路径下自带的main.dic的文件为扩展词典,stopword.dic为停用词典。
在这里插入图片描述
注意将文件格式另存为utf-8(不要选择utf-8 BOM)
要使用自定义词库,需要在配置文件 IKAnalyzer.cfg.xml 中 配置main.dic和stopword.dic,
在这里插入图片描述

3、index
index属性决定了该field能否作为检索条件。通过index属性指定是否对该 field 创建索引
默认为 index=true,即要进行索引,只有 field 创建了索引,才可以通过该 field 从索引库搜索到内容。对于一些不需要索引的内容,可以将index设置为false。

	"pic": {
  	   "type":"text",           
       "index":false
	}

4、source
source 属性决定了该field的内容是否作为结果展示。
如果只想存储某几个字段的原始值到Elasticsearch,可以通过incudes参数来设置,在mapping中的设置如下:

    POST /java06/course/_mapping
    {
      "_source": {
        "includes":["description"]
      }
    }

同样,可以通过excludes参数排除某些字段:

    POST /java06/course/_mapping
    {
      "_source": {
        "excludes":["description"]
      }
    }

五、ES 集群管理

ES 通常以集群方式工作,这样不仅提高了ES的搜索能力,而且增加了系统的容错能力及高可用。
下面是一个ES集群的示意图:该集群有三个主片,每个主片有两个副本,某个节点挂了也不怕,其他节点上还有副本。
在这里插入图片描述
添加文档过程:

  1. 用户将添加请求发送到节点1;
  2. 通过求余算法得知该文档应添加到主分片2,节点1就会将请求转发到节点3;
  3. 节点3上的主分片2会添加文档,然后将数据同步到1、2节点上的副本2;
    在这里插入图片描述
    查询文档过程:
    1、用户将查询请求发送到节点1;
    2、经过求余算法得知数据存储在分片2上,此时有3种选择,节点1上的副本2、节点2上的副本2和节点3上的主分片2;
    3、节点1通过负载均衡选中了节点2上的副本2,将请求转发给节点2;
    4、节点2把数据返回给节点1,节点1将数据返回给用户;
    在这里插入图片描述
    ES集群的状态
    集群的状态有3中颜色表示:
  • green:表示集群中所有的主分片和副本都正常;
  • yellow:表示集群中所有的主分片都正常,副本有部分挂掉;
  • red:表示集群中主分片和副本都有部分挂掉;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值