白日梦的ES笔记三:万字长文 Elasticsearch基础概念统一扫盲(一)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 白日梦的ES笔记三:万字长文 Elasticsearch基础概念统一扫盲(一)

一、导读#

本篇是白日梦的第三篇ES笔记,前面已经跟大家分享过两篇ES笔记了,分别是:

ES基础篇--快速上手ES

ES进阶篇--50个检索、聚合案例


其实这个专题相对来说质量还是比较不错的,看过前面两篇文章之后基本上大家可以上手使用ES了,包括对一些花里花哨的查询相关的写法也有所了解。然后这一篇文章会和大家调过头来重新巩固一下基础概念上的扫盲。


二、彩蛋福利:账号借用#



三、ES的Index、Shard及扩容机制#


首先你看下这个表格(ES6):


Elasticsearch 关系型数据库
Document
type(ES7中被取消)
index Database


在ES中的Index的地位相当于是MySQL中的database。所以你让ES帮你存储数据你总得

先创建一个Index吧,如果你手动的定制创建Index,你还可以为Index指定shard。

那什么是shard呢?下文马上说。


下面是对Index操作的Case:


# 创建索引
PUT my_index
{ 
  # 设置index的shard信息
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2
  },
  # 设置index中各个字段的类型,属性(下文细讲)
  "mapping":{
    ... 
  }
}
# 修改索引
PUT /my_index/_settings
{
  # 只能改number_of_replicas,不能改number_of_shards
  "number_of_replicas":3
}
# 删除索引
DELETE /my_index
DELETE /my_index1,my_index2
DELETE /my_*
DELETE /_all # 删掉所有索引
# 如果不想让ES可以一下子删除所有索引,可以通过配置文件设置
elasticsearch.yml
action.destructive_requires_name:true


shard分为primary shard和replica shard ,其中的primary shard可以接受读/写请求,replica shard可以接受读请求,起到一个负载的作用。默认情况下我创建的索引都有: number_of_shards = 5 和number_of_replicas = 1。表示一共有五个primary shard,并且每个primary 都有一个副本。也就是 5+5*1 =10个shard。


但是当你启动单台ES实例时,架构其实是下面这样:



你会发现,其实系统中就有5个shard。不存在上面计算的10个shard。原因是因为ES要求Primary Shard 和它的备份 replica shard不能同时存在于一个Node上。所以你单个Node启动后,就只有5个primary shard。并且这时你去看集群的状态,会发现整个集群处于yellow状态,表示集群整体可用,但是存在replica shard不可用的情况。


然后你会不会好奇,假设我有2个Node(两个ES实例)组成的ES集群,你怎样做,才能让系统中的Shard是如何负载均衡分布在两个Node上呢?


回答:其实你不用操心,ES自己会帮你完成的。当你增加或减少节点时,ES会自动的进行rebalance,使数据平均分散在不同的节点中。



举个例子:假设你真的又启动了一个Node,这个Node会自动的加入到上面那个ES中去,自动组成一个有两个Node的集群,如果你依然使用的默认配置即:


number_of_shards = 5 和 number_of_replicas = 1。这时ES会自动将系统rebalance成下图这样:



此时你再去看集群的状态,会发现为green。表示集群中所有shard都可用。


Node2中会存在5个replica shard,他们是Node1中的Primary的备份。每个shard相当于是一个luncene实例,拥有完整的检索数据、处理请求的能力。所以shard的数量越多,一定意义上意味着ES的吞吐量就越大。


但是你需要注意的是,primary shard的数量是不能改变的,但是它的副本的数量可以改变。


至于为什么primary shard的数量是不能改变的,下文中的路由原理会说的。


所以当你想对现在有的ES集群进行扩容的时,就存在两种选择:


1、纵向扩容:你不改变集群的总shard数,然后去买配置更高,存储更大的机器跑这些shard。

2、横向扩容:你扩大replica shard的数量,然后去多购置几个配置低的机器,你只需要写好配置文件,再启动Node,它自己会加入到现有的集群中。因为每个shard的都能对外提供服务嘛,所以你这样扩容系统的性能肯定有提升。


根据现在云服务器实例的市场行情来看,方案二会更省钱一些。


当然了如果你想让ES集群有最好的性能,还是使用默认的配置:number_of_shards = 5 和number_of_replicas = 1,这时你需要10台机器。每个集群上都启动一个ES实例,让这10个实例组建集群。就像下图这样:



这时每个shard都独享操作系统的所有资源,性能自然会最好。


四、ES支持的核心数据类型#


参考官网 https://www.elastic.co/guide/en/elasticsearch/reference/6.2/mapping-types.html


4.1、数字类型#


long、integer、short、byte、double、float、half_float、scaled_float


示例:


PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "number_of_bytes": {
          "type": "integer"
        },
        "time_in_seconds": {
          "type": "float"
        },
        "price": {
          "type": "scaled_float",
          "scaling_factor": 100
        }
      }
    }
  }
}


4.2、日期类型#


date


示例:


PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "birthday ": {
          "type": "date" 
        }
      }
    }
  }
}
PUT my_index/_doc/1
{ "date": "2015-01-01" }


4.3、boolean类型#


string类型的字符串可以被ES解释成boolean。


boolean


示例:


PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "is_published": {
          "type": "boolean"
        }
      }
    }
  }
}


4.4、二进制类型#


binary


示例


PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "name": {
          "type": "text"
        },
        "blob": {
          "type": "binary"
        }
      }
    }
  }
}
PUT my_index/_doc/1
{
  "name": "Some binary blob",
  "blob": "U29tZSBiaW5hcnkgYmxvYg==" 
}


4.5、范围#


integer_range、float_range、long_range、double_range、date_range


示例


PUT range_index
{
  "settings": {
    "number_of_shards": 2
  },
  "mappings": {
    "_doc": {
      "properties": {
        "expected_attendees": {
          "type": "integer_range"
        },
        "time_frame": {
          "type": "date_range", 
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
      }
    }
  }
}
PUT range_index/_doc/1?refresh
{
  "expected_attendees" : { 
    "gte" : 10,
    "lte" : 20
  },
  "time_frame" : { 
    "gte" : "2015-10-31 12:00:00", 
    "lte" : "2015-11-01"
  }
}


4.6、复杂数据类型#


对象类型,嵌套对象类型


示例:


PUT my_index/_doc/1
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
  }
}


在ES内部这些值被转换成这种样式


{
  "region":             "US",
  "manager.age":        30,
  "manager.name.first": "John",
  "manager.name.last":  "Smith"
}


4.7、Geo-type#


ES支持地理上的定位点。


PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "location": {
          "type": "geo_point"
        }
      }
    }
  }
}
PUT my_index/_doc/1
{
  "text": "Geo-point as an object",
  "location": { 
    "lat": 41.12,
    "lon": -71.34
  }
}
PUT my_index/_doc/4
{
  "text": "Geo-point as an array",
  "location": [ -71.34, 41.12 ] 
}


五、精确匹配与全文检索#


精确匹配和全文检索是ES提供的两种检索方式,都不难理解。


5.1、精确匹配:exact value#


搜索时输入的value必须和目标完全一致才算作命中。


"query": {
    # match_phrase 短语精确匹配的关键字
    # 只有name字段 完全等于 “白日梦”的doc 才算命中然后返回
    "match_phrase": { 
        "name": "白日梦" 
     } 
 }


5.2、全文检索:full text#


全文检索时存在各种优化处理如下:

  • 缩写转换: cn == china
  • 格式转换 liked == like == likes
  • 大小写转换 Tom == tom
  • 同义词转换 like == love

示例


GET /_search
{
    "query": {
        # match是全文检索的关键字
        # 白日梦可以被分词器分成:白、白日、白日梦
        # 所以当你使用:白、白日、白日梦、我是白日梦、白日梦是我 等等词条检索,都可以检索出结果
        "match" : {
            "name" : "白日梦"
        }
    }
}


六、倒排索引 & 正排索引#


6.1、倒排索引 inverted index#


其实正排索引和倒排索引都是人们取的名字而已。主要是你理解它是什么东西就好了。

正排索引:以doc为维度,记录doc中出现了哪些词。


倒排索引:以把doc打碎成一个个的词条,以词语为维度。记录它在哪些doc中出现过。

倒排索引要做的事就是将一篇文章通过分词器打散成很多词,然后记录各个词分别在哪篇doc中出现过。用户在使用的时候输入一串搜索串,这串字符串同样会使用一样的分词器打散成很多词。再拿着这些词去方才建立的倒排索引中匹配。同时结合相关性得分找到。


假设我们存在这样两句话。


doc1 : hello world you and me
doc2 : hi world how are you


建立倒排索引就是这样


词条 doc1(*表示出现过) doc2(-表示不曾出现过)
hello * -
world * *
you * *
and * -
me * -
hi - *
how - *
are - *


这时,我们拿着hello world you 来检索,同样需要先经过分词器分词,然后可以得到分出来的三个单词:hello、world、you,然后拿着这三个单词去上面的倒排索引表中找,


你可以看到:

  • hello在doc1中出现过。
  • world在doc1、doc2中出现过。
  • you在doc1、doc2中出现过。

最终doc1、doc2都会被检索出,但是doc1命中了更多的词,因此doc1得分会更高,排名越靠前。


6.2、正排索引 doc value#


doc value 是指所有不分词的document的field。


在建立索引的时候,一方面会建立倒排索引,以供搜索用。一方面会建立正排索引,也就是doc values,以供排序,聚合,过滤等操作使用。


正排索引大概长这样:


document name age
doc1 张三 12
doc2 李四 34


os cache会缓存正排索引,以提高访问doc value的速度。当OS Cache中内存大小不够存放整个正排索引时,doc value中的值会被写入到磁盘中。


关于性能方面的问题:ES官方建议,大量使用OS Cache来进行缓存和提升性能。不建议使用jvm内存来缓存数据,那样会导致一定的gc开销,甚至可能导致oom问题。所以官方的建议给JVM更小的内存,给OS Cache更大的内存。假如我们的机器64g,只需要给JVM 16g即可。


6.3、禁用doc value#


假设我们不使用聚合、排序等操作,为了节省空间,在创建mappings时,可以选择禁用doc value,不创建正排索引。


PUT /index
{
    "mappings":{
        "my_type":{
            "properties":{
                "my_field":{
                    "type":"text",
                    "doc_values":false # 禁用doc value
                }
            }
        }
    }
}


七、简述相关性评分#


relevance score 相关度评分算法, 直白说就是算出一个索引中的文本和搜索文本之间的相似程度。


Elasticsearch使用的是 TF-IDF算法 (term-frequency / inverser document frequency)。

  • term-frequency: 表示你搜索的词条在当前doc中出现的次数,出现的次数越多越相关。
  • inverse document frequency : 表示搜索文本中的各个词条在整个index中所有的document中出现的次数,出现的次数越多越不相关。
  • field-length: field长度越长,越不相关。
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 分布式计算 大数据
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
57 3
|
2月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
20天前
|
测试技术 API 开发工具
ElasticSearch核心概念:倒排索引
ElasticSearch核心概念:倒排索引
50 6
|
1月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
117 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
1月前
|
JSON 关系型数据库 API
ElasticSearch 的概念解析与使用方式(二)
ElasticSearch 的概念解析与使用方式(二)
25 1
|
1月前
|
存储 搜索推荐 Java
ElasticSearch 的概念解析与使用方式(一)
ElasticSearch 的概念解析与使用方式(一)
58 1
|
1月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
49 0
|
1月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
34 0
|
2月前
|
JSON 自然语言处理 数据库
ElasticSearch基础1——索引和文档。Kibana,RestClient操作索引和文档+黑马旅游ES库导入
概念、ik分词器、倒排索引、索引和文档的增删改查、RestClient对索引和文档的增删改查
ElasticSearch基础1——索引和文档。Kibana,RestClient操作索引和文档+黑马旅游ES库导入
|
3月前
|
自然语言处理 Java 索引
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作
41 0