但行好事 莫问前程

Elasticsearch基础概念详解

陈明羽 2019-05-10

微信搜索“我是树懒”或扫下方二维码关注公众号

优质文章,第一时间送达

elasticsearch

​ elasticsearch是一个近实时分布式搜索和分析引擎,它用于全文搜索、结构化搜索、分析以及将这三者混合使用,使用java编写,基于Lucene 实现

优势

  1. 分布式的实时文件存储,每个字段都被索引并可被搜索

  2. 实时分析的分布式搜索引擎

  3. 横向可扩展:支持上百台服务节点的扩展,集群增加机器简单,支持处理PB级数据

  4. 分片机制:

    允许水平分割扩展数据,允许分片和并行操作从而提高性能和吞吐量

    提供高性能:同一个索引可以分多个主分片(primary shard),每个主分片拥有自己的副本分片(replica shard),每个副本分片都可以提供服务,提升系统搜索请求的吞吐量和性能

    提供高可用性:同一个索引可以分多个主分片,每个主分片拥有零个或者多个副本,如果主分片挂了,可以从副本分片中选择一个作为主分片继续提供服务

  5. 隐藏复杂实现:Elasticsearch 内部隐藏了分布式系统的复杂性,我们不用去关心它是如何做到高可用,可扩展,高性能的

  6. 易用开源:不需要额外配置,就可以运行一个Elasticsearch服务,开源

基本概念

  1. Cluster:集群

    一个集群包含多个节点,对外提供服务,每个节点属于哪个集群通过配置文件中的集群名称决定

  2. Node:节点

    集群中的一个节点,每个节点也有一个名称,默认是随机分配,也可以自己指定,在es集群中通过节点名称进行管理和通信

  3. Index:索引

    索引是具有相同结构的文档集合,作用相当于mysql中的库

  4. Type:类型

    一个索引可以对应一个或者多个类型,类型可以当做是索引的逻辑分区,作用相当于mysql中的表

  5. Document:文档

    存储在es中的一个JSON格式的字符串,每一个文档有一个文档ID,如果没有自己指定ID,系统会自动生成一个ID,文档的index/type/id必须是唯一的,作用相当于mysql中的行

  6. field:字段

    一个文档会包含多个字段,每个字段都对应一个字段类型,类似于mysql中的列

  7. shard:分片

    es中分为primary shard主分片和replica shard副本分片

    主分片:当存一个文档的时候会先存储在主分片中,然后复制到不同的副本分片中,默认一个索引会有5个主分片,当然可以自己指定分片数量,当分片一旦建立,分片数量不能改变

    副本分片:每一个主分片会有零个或者多个副本,副本主要是主分片的复制,通过副本分片可以提供高可用性,当一个主分片挂了,可以从副本分片中选择一个作为主分片,还可以提高性能,所以主分片不能和副本分片部署在相同的节点上

  8. replica:复制

    复制是为了防止单点问题,可以做到对故障进行转移,保证系统的高可用

  9. 映射

    描述数据在每个字段内如何存储,是定义存储和索引的文档类型及字段的过程,索引中的每一个文档都有一个类型,每种类型都有它自己的映射,一个映射定义了文档结构内每个字段的数据类型

    使用GET /index/_mapping/type获取对应的/index/type的映射信息

可视化界面Kibana

建议安装Elasticsearch+Kibana,在Kibana的操作界面对es进行操作

Elasticsearch提供了RESTful接口可以对Elasticsearch进行操作

Kibana操作页面

在Kibana的Dev Tools界面可以对es进行操作,在console界面敲命令,点执行,会在右面输出结果

验证Elasticsearch是否安装成功

http://localhost:9200/?pretty

{
  "name" : "UzOujcc", //节点名称
  "cluster_name" : "mx", //集群名称,我自己设置的
  "cluster_uuid" : "d2K1M95DRzG9XOPDOR_DEQ",
  "version" : {
    "number" : "6.2.4", //集群版本
    "build_hash" : "ccec39f",
    "build_date" : "2018-04-12T20:37:28.497551Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

es提供了一套api,叫做cat api,可以查看es中的信息数据

查看集群健康状况

命令:GET /_cat/health?v

status代表着集群的健康程度

  1. green:每个索引的primary shard和replica shard都是active状态的
  2. yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态
  3. red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了

索引操作

查看索引信息

命令:GET _cat/indices?v

有五个索引,都是的测试数据

新建索引

命令:PUT /myindex

{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "myindex"
}

删除索引

命令:DELETE myindex

{
  "acknowledged": true
}

文档操作

添加文档

添加文档是向索引中添加一条文档,让其能够搜索,文档格式是json串,如果es中有相同id的文档存在则更新这个文档

当创建文档的时候,如果索引不存在,则会自动创建该索引,而且es默认会对document每个field都建立倒排索引,让其可以被搜索

命令:

PUT /index/type/id 
{ 
    "json数据结构体 "
}

例:

PUT /school/student/1
{
  "name":"张三",
  "age":21,
  "class":2,
  "gender":"男"
}

返回:

{
  "_index": "school", //索引
  "_type": "student", //类型
  "_id": "1", //id,如果不指定则会系统生成一个20位的id,文档被分到那个分片上就是根据id的散劣值进行控制
  "_version": 1, //文档版本号,通过这个进行并发控制
  "result": "created", //操作类型
  "_shards": { //分片信息
    "total": 2, //文档被创建时在多少个分片进行了操作(包括主分片和副本分片)
    "successful": 1, //添加成功的索引分片数量
    "failed": 0 //失败的索引分片数量
  },
  "_seq_no": 0,
  "_primary_term": 1
}

修改文档

方式1:使用put方式更新文档

PUT /school/student/1
{
  "name":"吕布",
  "age":21,
  "class":2,
  "gender":"男"
}

返回:

{
  "_index": "school",
  "_type": "student",
  "_id": "1",
  "_version": 2, //版本号+1
  "result": "updated", // 修改
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 1,
  "_primary_term": 1
}

这种方式替换需要带上所有的field,才能进行信息的修改,操作类似于覆盖

方式2:post更新文档

POST /school/student/1/_update
{
  "doc": {
    "name":"吕布1"
  }
}

使用post更新文档,可以只更新部分字段

查询文档

查询单条文档

命令:GET /school/student/1

返回:

{
  "_index": "school",
  "_type": "student",
  "_id": "1",
  "_version": 3,
  "found": true,
  "_source": {
    "name": "吕布1",
    "age": 21,
    "class": 2,
    "gender": "男"
  }
}

删除文档

命令:DELETE school/student/1

返回:

{
  "_index": "school",
  "_type": "student",
  "_id": "1",
  "_version": 4,
  "result": "deleted", //删除
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 3,
  "_primary_term": 1
}

这时在查询就会显示"found": false

映射

es中的映射(mapping)用来描述数据在每个字段内如何存储,是定义存储和索引的文档类型及字段的过程,索引中的每一个文档都有一个类型,每种类型都有它自己的映射,一个映射定义了文档结构内每个字段的数据类型,作用相当于mysql中的DDL语句

查询索引类型的映射

GET /ad/_mapping/phone

{
  "school": {
    "mappings": {
      "student": {
        "properties": {
          "age": {
            "type": "long"
          },
          "class": {
            "type": "long"
          },
          "gender": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

动态映射

动态映射不需要事先定义映射,文档在写入es的时候,会根据文档字段自动识别类型

映射规则:

Json 数据类型 es 数据类型
null 没有字段添加
true,false boolean
Integer long
object object
array 依赖于数组中首个非空值
string text和keyword
日期 date或text

静态映射

静态映射需要事先定义好映射,包含文档的各个字段及其类型

PUT books
{
  "mappings": {
    "book":{
      "properties": {
        "id":{"type": "long"},
        "bookName":{"type": "text"},
        "ad":{"type": "text"}
      }
    }
  }
}

Elasticsearch 中的数据可以概括的分为两类:精确值和全文

  1. 精确值:精确值是确定的值,比如用户ID,字符串也可以表示精确值,例如用户名或邮箱地址。对于精确值来讲,Foofoo 是不同的,精确值的查询简单,要么匹配查询,要么不匹配
  2. 全文:全文是指文本数据(通常以人类容易识别的语言书写),例如一个推文的内容或一封邮件的内容,全文的查询较为复杂,他需要的是匹配查询的程度有多大

在es中使用 倒排索引来进行快速的全文搜索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表,倒排索引具体内容请戳:https://www.elastic.co/guide/cn/elasticsearch/guide/current/inverted-index.html

es中的字符串类型分为keywordtext

  1. keyword:用于索引结构化内容的字段,例如电子邮件地址,主机名,状态代码,邮政编码或标签。它们通常用于过滤,排序,和聚合。keyword字段只能按其确切值进行搜索。如果您需要索引电子邮件正文或产品说明等全文内容,则可能应该使用text字段
  2. text:用于索引全文值的字段,例如电子邮件正文或产品说明。这些字段是analyzed,它们通过分词器传递 ,以在被索引之前将字符串转换为单个术语的列表。分析过程允许Elasticsearch搜索单个单词中 每个完整的文本字段。文本字段不用于排序,很少用于聚合

有时候一个字段同时拥有全文类型(text)和关键字类型(keyword)是有用的:一个用于全文搜索,另一个用于聚合和排序。这可以通过多字段类型来实现(动态映射是字符串的默认映射类型)

参考: Elasticsearch: 权威指南(版本较老,可以看新的)https://www.elastic.co/guide/cn/elasticsearch/guide/cn/index.html

使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章