ElasticSearch核心技术解析:倒排索引与IK分词器如何解决中文搜索痛点

在传统数据库中,模糊查询往往难以应对现实中的复杂情况。随着数据量的增加,查询时间显著变慢,功能也相对单一。当搜索时出现错别字或拼音输入时,搜索结果往往不尽如人意。因此,我们需要学习一种强大的搜索框架技术------ElasticSearch。

倒排索引

在传统的模糊搜索中,系统会从表中逐条读取数据,筛选出与模糊搜索条件相关的记录。这种方式通常使用B+树来建立索引,但由于索引与每条数据的内容没有直接关联,导致搜索时需要逐条检索,效率较低。

倒排索引

倒排索引是ElasticSearch等现代搜索引擎的核心技术之一。它引入了文档词条两个概念:

  • 文档:相当于数据库中的一条记录。

  • 词条:对文档内容进行分词处理。例如,句子"我是倒排索引"可以通过特定算法拆分为"我"、"是"、"倒排"、"索引"等词条。这些词条可能还包含其他语义相关的词语。

倒排索引的工作原理

假设我们有以下商品数据:

  1. "黑玩具"

  2. "红玩具"

  3. "红书包"

倒排索引会对这些文档进行词条划分,并建立词条与文档编号的映射关系:

  • 黑:1

  • 玩具:1, 2

  • 红:2, 3

  • 书包:3

当用户搜索"粉玩具"时,系统会首先对搜索词进行分词处理,得到"粉"和"玩具"两个词条。然后,系统会在倒排索引中查找这些词条对应的文档编号:

  • "粉"没有对应的文档编号。

  • "玩具"对应的文档编号是1和2。

最终,系统会返回文档编号为1和2的结果。由于词条和文档编号都建立了索引,搜索效率非常高。

倒排索引的优势

  1. 高效检索:通过词条与文档编号的映射,系统可以快速定位相关文档,避免了全表扫描。

  2. 容错性强:即使搜索词中存在错别字或拼音输入,系统仍然可以通过分词和索引匹配找到相关结果。

  3. 支持复杂查询:倒排索引支持多种查询方式,如布尔查询、短语查询、范围查询等,能够满足多样化的搜索需求。

IK分词器

ElasticSearch 依靠倒排索引来实现高效的全文搜索,而倒排索引的核心在于分词。对于中文文本,分词尤为重要,因为中文不像英文那样有天然的空格分隔。IK分词器是一个专门为中文设计的分词器,它能够将连续的汉字序列切分成有意义的词语,而不是简单地将每个字分开。这种分词方式不仅保留了语句的完整性,还方便了词条的创建和索引。

在 IK 分词器的配置中,IKAnalyzer.cfg.xml 文件用于对分词行为进行定制化配置。例如,当网络新梗或流行语出现时,传统的分词规则可能无法正确识别这些新词,导致分词结果不准确。通过修改配置文件,我们可以动态地扩展词典或调整分词规则,以适应实际需求。

以下是一个典型的 IKAnalyzer.cfg.xml 配置文件示例:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<entry key="ext_dict">ext.dic</entry>
	<entry key="ext_stopwords"></entry>
</properties>
配置文件解析:
  1. ext_dict :用于指定扩展词典文件(如 ext.dic)。扩展词典允许用户添加新词或专有名词,确保这些词在分词时不会被错误地拆分。例如,网络流行语"内卷"、"躺平"等可以通过扩展词典加入分词器的词库。

  2. ext_stopwords:用于指定停用词文件。停用词是指在文本中出现频率较高但对搜索结果影响较小的词,例如"的"、"了"、"是"等。通过配置停用词,可以减少索引的大小,提高搜索效率。

IK分词器的两种模式:
  1. ik_smart :智能分词模式,采用粗粒度分词策略。这种模式会将文本切分成较少的词条,适合用于搜索引擎的初步筛选。例如,句子"人工智能技术"在 ik_smart 模式下可能只会分成"人工智能"和"技术"两个词条。

  2. ik_max_word :细粒度分词模式,采用最大分词策略。这种模式会尽可能多地将文本切分成不同的词条,适合用于需要高精度的场景。例如,句子"人工智能技术"在 ik_max_word 模式下可能会分成"人工"、"智能"、"人工智能"、"技术"等多个词条。

基本概念

ElasticSearch 的许多概念可以从 MySQL 中延伸理解:

  • 索引(Index):相当于 MySQL 中的表(Table),用于存储相关数据。

  • 字段(Field):相当于 MySQL 中的列(Column),用于定义数据的属性。

  • 文档(Document):相当于 MySQL 中的一行数据(Row),但在 ElasticSearch 中,文档是以 JSON 格式存储的。

  • 映射(Mapping):相当于 MySQL 的表结构(Schema),用于定义字段的数据类型和约束。

与 MySQL 不同,ElasticSearch 将每一行数据转换为 JSON 格式存储,这种设计使其在处理非结构化或半结构化数据时更加灵活。此外,ElasticSearch 在应对大规模数据搜索场景时表现出更高的效率,尤其是在全文搜索和复杂查询方面。

然而,MySQL 在数据安全性和事务支持方面更具优势,适合需要强一致性和复杂事务处理的场景。

索引库操作

索引相当于数据库中的表, 映射相当于数据库的表结构, 用来进行数据的约束, 要想进行倒排索引就要设置索引和映射

Mapping映射属性

在数据建模和搜索引擎配置中,映射属性(Mapping)用于定义字段的类型及其处理方式。以下是常见的字段类型及其相关属性:

字段类型
  1. 字符串类型:

    • Text: 适用于需要分词的文本字段

    • Keyword: 适用于不需要分词的精确文本,如品牌名称、国家代码等。

  2. 数字类型:

    • Integer: 32位整数。

    • Long: 64位整数。

    • Short: 16位整数。

    • Double: 双精度浮点数。

    • Float: 单精度浮点数。

    • Byte: 8位整数。

  3. 布尔类型:

    • Boolean: 表示真或假的值。
  4. 日期类型:

    • Date: 用于存储日期和时间。
  5. 对象类型:

    • Object: 用于嵌套的复杂数据结构。
其他属性
  • Index : 确定字段是否被索引。如果设置为false,该字段将不会被搜索,但仍可存储在文档中。

  • Properties: 用于定义嵌套字段或子字段的结构。

  • Analyzer : 指定用于分词的分词器类型,适用于Text类型的字段。

索引库

索引库的创建与映射设置

  1. 创建索引库并设置映射
    • 在Elasticsearch中,创建索引库的同时可以定义映射(mappings),映射用于描述索引库中文档的结构,包括字段的类型等信息。以下是创建索引库并设置映射的基本操作:
    • 使用PUT请求来创建索引库并设置映射。例如,创建一个名为my_index的索引库:
      • 在上述示例中:

        • 对于title字段,它被定义为text类型,并且还定义了一个子字段keyword,这个子字段也是keyword类型。这种结构很常见,text类型适合用于全文搜索,而keyword类型适合用于精确匹配,比如过滤或者排序。
        • 对于price字段,它是double类型,并且设置了"index": false。这意味着这个字段不会被索引,不能用于搜索,但可以在查询结果中返回该字段的值。

        PUT /my_index
        {
        "mappings": {
        "properties": {
        "title": {
        "type": "text",
        "fields": {
        "keyword": {
        "type": "keyword"
        }
        }
        },
        "price": {
        "type": "double",
        "index": false
        }
        }
        }
        }

获取索引库​​​

  1. 查询索引库是否存在及基本信息
    • 使用GET请求可以获取索引库的信息。例如,要获取名为my_index的索引库的信息:
      • 如果索引库存在,Elasticsearch会返回该索引库的各种元数据信息,如索引的设置(包括分片数量、副本数量等)、映射等信息。如果索引库不存在,则会返回相应的错误提示。

        GET /my_index

添加新字段

  1. 注意事项
    • 在Elasticsearch中,如果直接在已经存在的索引库中进行字段修改,可能会导致倒排索引重新排列。当索引库中的数据量非常庞大时,这个操作可能会消耗大量的资源,甚至可能使服务器瘫痪。
  2. 正确的添加新字段方式
    • 要添加新字段,应该使用PUT请求针对索引库的_mapping端点进行操作。例如,要在my_index索引库中添加一个名为description的新字段,类型为text
      • 这种方式相对比较安全,并且Elasticsearch会根据新的映射调整索引结构,尽量减少对现有数据和搜索性能的影响。

        PUT /my_index/_mapping
        {
        "properties": {
        "description": {
        "type": "text"
        }
        }
        }

删除索引库

  1. 执行删除操作
    • 如果要删除一个名为my_index的索引库,可以使用DELETE请求:
      • 在执行删除操作之前,需要谨慎考虑,因为一旦索引库被删除,其中所有的数据都将永久丢失,并且无法恢复。

        DELETE /my_index

文档操作

新增文档

  1. 基本语法
    • 使用POST请求向指定索引库的_doc路径下添加文档,并可指定文档ID。

    • 格式:POST /索引库名/_doc/文档id

    • 示例:

      POST /my_index/_doc/1
      {
      "title": "示例文档",
      "content": "这是新增文档的内容"
      }

    • 若不指定文档ID,Elasticsearch会自动生成一个唯一ID。

      POST /my_index/_doc/
      {
      "title": "自动生成ID的文档",
      "content": "内容"
      }

获取文档

  1. 基本语法
    • 使用GET请求通过索引库名、_doc路径和文档ID来获取特定文档。
    • 格式:GET /索引库名/_doc/{id}
    • 示例:
      • 若文档存在,将返回该文档的详细信息;若不存在,会返回相应错误提示。

        GET /my_index/_doc/1

删除文档

  1. 基本语法
    • 使用DELETE请求通过索引库名、_doc路径和文档ID来删除特定文档。
    • 格式:DELETE /索引库名/_doc/{id}
    • 示例:
      • 成功删除会返回相应成功提示,若文档不存在则返回错误提示。

        DELETE /my_index/_doc/1

修改文档

一、全量修改

  1. 操作原理
    • 全量修改意味着对文档进行较为彻底的更新操作。如果目标文档在索引库中已经存在,那么会先删除原来的文档,然后再新增一个文档。如果该文档在索引库中原本就不存在,则会直接重新创建这个文档。
  2. 操作示例
    • 假设我们有一个名为"my_index"的索引库,并且要修改或者创建一个id为"1"的文档。其操作如下:

    • 使用的API为:PUT /my_index/_doc/1

    • 文档内容示例:

      {
      "title": "新的标题",
      "content": "这是全新的内容"
      }

二、局部修改

  1. 操作原理
    • 局部修改主要是针对文档的部分属性进行修改。这种修改方式不需要删除整个文档再重新创建,而是只更新指定的部分属性,从而节省资源和时间。
  2. 操作示例
    • 同样以"my_index"索引库中id为"1"的文档为例,如果只想修改其中"title"这个属性。

    • 使用的API为:POST /my_index/_update/1

    • 文档内容示例:

      {
      "doc": {
      "title": "修改后的标题"
      }
      }

相关推荐
汤姆yu4 分钟前
基于python大数据的旅游可视化及推荐系统
大数据·旅游·可视化·算法推荐
zhangjin122219 分钟前
kettle从入门到精通 第九十四课 ETL之kettle MySQL Bulk Loader大批量高性能数据写入
大数据·数据仓库·mysql·etl·kettle实战·kettlel批量插入·kettle mysql
哈哈真棒1 小时前
hadoop 集群的常用命令
大数据
阿里云大数据AI技术1 小时前
百观科技基于阿里云 EMR 的数据湖实践分享
大数据·数据库
泛微OA办公系统1 小时前
上市电子制造企业如何实现合规的质量文件管理?
大数据·制造
GOTXX2 小时前
BoostSiteSeeker项目实战
前端·c++·后端·mysql·搜索引擎·项目实战·boost
镜舟科技2 小时前
迈向云原生:理想汽车 OLAP 引擎变革之路
大数据·数据库·云原生
山山而川粤2 小时前
SSM考研信息查询系统
java·大数据·运维·服务器·开发语言·数据库·考研
rkshangan3 小时前
软考高级:探寻易考科目与高效备考之路
大数据·网络
mooyuan天天5 小时前
黑帽SEO之搜索引擎劫持-域名劫持原理分析
搜索引擎·seo搜索引擎劫持·seo域名劫持