Elastic Search的倒排索引库

一、什么是Elastic Search

ElasticSearch(简称ES)是一个基于Apache Lucene构建的开源搜索引擎,它提供了一个分布式、可扩展的全文搜索和分析引擎。ElasticSearch被设计用来处理大量数据,并能够快速执行复杂的搜索查询。它广泛应用于日志分析、安全情报、全文搜索、业务分析等领域。 

ElasticSearch使用倒排索引(Inverted Index)作为其核心数据结构,以实现快速的全文搜索功能。

二、什么是倒排索引

先来了解几个概念。

文档( Document ):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息。

词条 Term ):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是
。例如:我是中国人,就可以分为:我、是、中国人、中国、国人这样的几个词条。 

什么是正向索引?例如给下表(tb_goods)中的id创建索引:  

如果是根据 id 查询,那么直接走索引,查询速度非常快。 但如果是基于title 做模糊查询,只能是逐行扫描数据,流程如下:  
  • 用户搜索数据,条件是title符合 "%手机%"。
  • 逐行获取数据,比如id1的数据。
  • 判断数据中的title是否符合用户搜索条件。
  • 如果符合则放入结果集,不符合则丢弃。回到步骤1。

如下图所示:

逐行扫描,也就是全表扫描,随着数据量增加,其查询效率也会越来越低。当数据量达到数百万时,就是一场灾难。
创建倒排索引 是对正向索引的一种特殊处理,流程如下:
  • 将每一个文档的数据利用算法分词,得到一个个词条。
  • 创建表,每行数据包括词条、词条所在文档id位置等信息。
  • 因为词条唯一性,可以给词条创建索引,例如hash表结构索引。

如下图所示:

倒排索引的 搜索流程 如下(以搜索 " 华为手机 " 为例):
  • 用户输入条件 "华为手机" 进行搜索。
  • 对用户输入内容分词,得到词条: 华为 手机
  • 拿着词条在倒排索引中查找,可以得到包含词条的文档id123
  • 拿着文档id到正向索引中查找具体文档。

如下图所示: 

虽然要先查询倒排索引,再查询正向索引,但是无论是词条、还是文档id都建立了索引,查询速度非常快!无需全表扫描。

总结来说,倒排索引(Inverted Index)是一种特殊的索引结构,广泛应用于全文搜索引擎中。

它的核心思想是将文档集中的词汇与其出现的文档位置反向关联起来,即不是按照文档来索引词汇,而是按照词汇来索引包含它们的文档。

这样的设计使得搜索引擎能够快速地根据用户查询中的关键词找到包含这些关键词的文档集合。 

三、为什么要创建倒排索引库 

倒排索引之所以被创建,是因为它在全文检索中提供了极高的效率

传统的正向索引(正排索引)是按照文档来组织词汇的,这意味着要查找一个词汇在哪些文档中出现,需要逐个检查每个文档。

倒排索引则是按照词汇来组织文档的,它将每个词汇映射到包含该词汇的所有文档的列表,这样可以直接通过词汇快速找到相关文档,大大减少了搜索时间。

四、倒排索引库的操作

索引库就类似数据库mapping映射就类似表的结构。 我们要向ES中存储数据,必须先创建“

数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。

常见的mapping属性包括:

  • type:字段数据类型,常见的简单类型有:

    • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)。

    • 数值:longintegershortbytedoublefloat。

    • 布尔:boolean。

    • 日期:date。

    • 对象:object。

  • index:是否创建索引,默认为true。

  • analyzer:使用哪种分词器。

  • properties:该字段的子字段。

下面是关于索引库的一些操作: 

1.创建索引库和mapping映射

PUT /索引库名称
{
  "mappings": {
    "properties": {
      // 定义文本字段,使用ik_smart分析器
      "title": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      // 定义一个不被索引的keyword字段
      "id": {
        "type": "keyword",
        "index": "false"
      },
      // 定义一个嵌套对象,其中包含一个keyword类型的子字段
      "author": {
        "properties": {
          "name": {
            "type": "keyword"
          }
        }
      }
      // 其他字段定义可以继续添加
    }
  }
}

例如:

{
    "age":18,
    "weight":60.5,
    "isMarried":false,
    "email":"12321@qq.com",
    "name":{
        "firstName":"王"
    }
}

2.删除索引库

DELETE /my_index

五、文档操作

1.新增文档

PUT /索引库名称/_doc/文档ID
{
  "字段名": "值",
  "字段名2": "值2",
  // 其他字段...
}

例如:

PUT /my_index/_doc/1
{
  "title": "示例文档",
  "content": "这是一个示例文档的内容。",
  "author": "张三"
}

2.删除文档

DELETE /索引库名称/_doc/文档ID

例如:

DELETE /my_index/_doc/1

3.修改文档

此处为增量修改,只修改指定id匹配的文档中的部分字段。

POST /索引库名称/_update/文档ID
{
  "doc": {
    "字段名": "新值",
    // 其他需要修改的字段...
  }
}

 例如:

POST /my_index/_update/1
{
  "doc": {
    "title": "修改后的文档标题",
    "content": "这是修改后的文档内容。"
  }
}

4.查询文档

GET /索引库名称/_search
{
  "query": {
    "match": {
      "字段名": "查询值"
    }
  }
}

例如:

GET /my_index/_search
{
  "query": {
    "match": {
      "title": "示例文档"
    }
  }
}

注意: 

  • 文档ID在新增文档时需要指定,可以自定义,如果省略则由系统自动生成。

  • 修改文档时使用_update端点,并在请求体中使用“doc”字段来指定需要修改的部分。

  • 查询文档时,match查询是最基本的全文搜索,可以根据需要替换为更复杂的查询结构。

当然,关于ES还有很多内容,后续有时间我们再讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值