ElasticSearch核心知识讲解(一)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: ElasticSearch核心知识讲解

倒排索引

倒排索引作为ES的核心,底层基于Lucene进行实现。

倒排索引(Inverted Index)也叫反向索引,有反向索引必有正向索引。通俗地来讲,正向索引是通过文档ID找单词,类似于书的目录结构。反向索引则是通过单词找文档ID,类似于字典查词,首先必须知道单词的全拼,然后通过字典的索引页再去查找单词的详情。

640.png

倒排索引建立流程

  • 内容爬取,停顿词过滤,比如一些无用的像"的",“了”之类的语气词/连接词
  • 内容分词,提取关键词。一段文本经过分词器分词后转换成多个Term关键词。
  • 根据关键词建立倒排索引。倒排索引包括Term Index(单词索引),Term Dictionary(单词字典),Posting List(倒排列表)
    用户输入关键词进行搜索。
    640.png

倒排索引具体组成

640.jpg

单词词典(Term Dictionary): 包含了所有数据在进行分词之后生成的单词(term),词典是由所有term构成的字符串集合。搜索引擎的通常索引单位是term,词典内每条索引项记载term本身的一些信息以及指向“倒排列表”的指针。ES 为了能快速查找到 term,将所有的 term 排了一个序,并采用二分法进行查找。


倒排列表(PostingList): 倒排列表记载了出现过某个单词的所有文档的文档列表记录,每条记录称为一个倒排索引项(Posting),其主要包括:

  • 文档ID,用于获取原始信息
  • 单词频率TF,记录该单词在该文档中的出现次数,用于后续相关性算分
  • 位置Position,记录单词在文档中分词的位置,用于语句搜索(phrase query)
  • 偏移Offset,记录单词在文档的开始和结束位置,实现高亮显示

根据倒排列表,即可获知某个单词在哪些文章中出现过。

单词索引(Term Index): ES 默认会对全部 text 字段进行分词并建立索引,导致Term Dictionary过大,无法存储在内存中。为了更快的找到某个Term,我们为单词建立索引。Term Index采用字典树结构,这棵树不会包含所有的 term,它包含的是 term 的一些前缀,通过 term index 可以快速地定位到 term dictionary 的某个 offset,然后从这个位置再往后顺序查找。就如上图所表示的。单词索引文件是为了加快对词典文件中词的查找速度,存储在内存中。

lucene 在这里还做了两点优化,一是 term dictionary 在磁盘上面是分 block 保存的,一个 block 内部利用公共前缀压缩,比如都是 Ab 开头的单词就可以把 Ab 省去。

二是 term index 在内存中是以 FST(finite state transducers)的数据结构保存的。

分词

在构建倒排索引的过程中,需要对文档内容进行分词,掌握分词要先懂两个名词:Analysis与Analyzer。

Analysis(文本分析)

即文本分析,是把全文本转化为一系列单词(term/token)的过程,也叫分词;Analysis是通过analyzer(分词器)来实现的,可以使用Elasticearch内置的分词器,也可以自己去定制一些分词器。

Analyzer(分词器)

由三部分组成

  1. Character Filters:原始文本处理
    首先,字符串按顺序通过每个字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and。
    Tokenizer:按照规则切分为单词
    字符串被分词器按照规则分为单个的单词。一个 whitespace的分词器遇到空格和标点的时候,可能会将文本拆分成词条。下图为ES分词器汇总
    640.png
  2. Token Filters:字段过滤器,对切分单词加工、小写、删除 stopwords,增加同义词
    词条按顺序通过每个字段过滤器 。这个过程可能会改变词条,例如,lowercase token filter  小写化(将ES转为es)、stop token filter 删除词条(例如, 像 a, and, the 等无用词),或者synonym token filter 增加词条(例如,像 jump 和 leap 这种同义词)。

分词测试

使用index中的具体字段的分词器进行测试

下面的案例就是使用了index_name中的my_test字段所用的分词器进行测试。

GET ip:port/index_name/_analyze
{
  "field": "my_text",
  "text": "关注我,学习ES"
}

测试结果如下,从结果我们可以推测my_text字段使用的是standard分词器,按照每个词进行切分,且做小写处理。

{
    "tokens": [当前字段切分后出现的分词列表,由该词的文本、偏移量(开始和结束)、位置、以及类型组成;
        {
            "token": "关",//分词后的具体文本
            "start_offset": 0,//起始位置
            "end_offset": 1,//结束位置
            "type": "<IDEOGRAPHIC>",//当前单词的类型
            "position": 0//当前单词所在整个字段的位置。
        },
        {
            "token": "注",
            "start_offset": 1,
            "end_offset": 2,
            "type": "<IDEOGRAPHIC>",
            "position": 1
        },
        {
            "token": "我",
            "start_offset": 2,
            "end_offset": 3,
            "type": "<IDEOGRAPHIC>",
            "position": 2
        },
        {
            "token": "学",
            "start_offset": 4,
            "end_offset": 5,
            "type": "<IDEOGRAPHIC>",
            "position": 3
        },
        {
            "token": "习",
            "start_offset": 5,
            "end_offset": 6,
            "type": "<IDEOGRAPHIC>",
            "position": 4
        },
        {
            "token": "es",
            "start_offset": 6,
            "end_offset": 8,
            "type": "<ALPHANUM>",
            "position": 5
        }
    ]
}

也可以直接使用analyzer

POST ip:port/_analyze
{
  "analyzer": "whitespace",//这里使用空格分词器
  "text":"关注我 学习ES"
}

可以看到,空格分词器直接采用空格进行切分,并不会对文中英文字母进行小写处理。

{
    "tokens": [
        {
            "token": "关注我",
            "start_offset": 0,
            "end_offset": 3,
            "type": "word",
            "position": 0
        },
        {
            "token": "学习ES",
            "start_offset": 4,
            "end_offset": 8,
            "type": "word",
            "position": 1
        }
    ]
}

从以上测试可以看出,分析器不仅将原始文档转换为term,而且还记录每个term的顺序或相对位置(用于短语查询或单词接近性查询),以及每个term的开始和结束字符偏移量(用于突出显示搜索摘要)。

mapping

ES中的mapping映射可以把它类比于数据库中的表结构定义 schema,它有以下几个作用:

  • 定义索引中的字段的名称
  • 定义字段的数据类型,比如字符串、数字、布尔
  • 定义字段,倒排索引的相关配置,比如设置某个字段的分词器,是否可索引、记录 position 等

字段数据类型

字段的数据类型由字段的type属性指定,ES 字段类型主要有:核心类型、复杂类型、地理类型以及特殊类型,具体的数据类型如下图所示:

640.png

核心类型

从图中可以看出核心类型可以划分为字符串类型、数字类型、日期类型、布尔类型、基于 BASE64 的二进制类型、范围类型。

字符串类型

ES7.x有两种字符串类型:text和keyword,ES 5.x之后不再支持string 类型。

text 类型适用于需要被全文检索的字段,例如新闻正文、邮件内容等比较长的文字,text 类型会被分词器处理为一个个关键词后分别进行索引,支持模糊、精确查询,不支持聚合、排序操作。

keyword 与text不同,字段设置为此类型后,将不会进行分词操作直接索引。适合简短、结构化的字符串,可以用于过滤、排序、聚合检索,也可以用于精确查询。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
存储 数据采集 监控
Elasticsearch的优势
Elasticsearch的优势
|
14天前
|
存储 监控 安全
扩展 Elasticsearch
扩展 Elasticsearch
27 2
|
6月前
|
存储 监控 NoSQL
RedisSearch与Elasticsearch:技术对比与选择指南
RedisSearch与Elasticsearch:技术对比与选择指南
|
7月前
|
存储 搜索推荐 索引
5个 Elasticsearch 核心组件
Elasticsearch 是基于 Lucene 的分布式搜索引擎,具备高可用和多租户特性。其核心组件包括:节点(Node)、集群(Cluster)、索引(Index)、分片(Shard)和副本(Replica)。节点是集群中的服务器,可设置为主、数据或客户端节点。集群由多个节点组成,通过集群名称区分。索引是文档集合,7.x 版本后每个索引仅含一种类型。分片是索引的子集,可分布于不同节点,分为主分片和副本分片,副本用于提高数据可用性和性能。【5月更文挑战第5天】
|
存储 自然语言处理 负载均衡
|
存储 Java 索引
【ElasticSearch从入门到放弃系列 八】Elasticsearch集群深度探讨
【ElasticSearch从入门到放弃系列 八】Elasticsearch集群深度探讨
145 0
|
存储 SQL 自然语言处理
1.【Elasticsearch】Elasticsearch从入门到放弃-Elasticsearch概念篇
【Elasticsearch】Elasticsearch从入门到放弃-Elasticsearch概念篇
|
存储 JSON 定位技术
ElasticSearch核心知识讲解(二)
ElasticSearch核心知识讲解
214 0
|
存储 JSON 自然语言处理
ElasticSearch核心知识讲解
ElasticSearch核心知识讲解
340 0
ElasticSearch核心知识讲解
|
存储 数据采集 数据可视化
Elasticsearch具有以下优势:
Elasticsearch具有以下优势:
540 0