当前位置: 首页 > article >正文

Elasticsearch 检索优化:停用词的应用

Elasticsearch 检索优化:停用词的应用

场景描述

目前在 Elasticsearch 集群中存储约 1.5 亿篇文章数据,随着数据量的增加,检索性能问题逐渐显现。在列表检索和聚合操作中,CPU 消耗飙升至 100%,并且检索耗时较长:

  • 列表检索耗时:5+ 秒
  • 聚合检索耗时:12+ 秒
  • 索引大小:623.40GB

实例

一个典型的检索词为:
Non-capital histories: book distribution in publishing houses of Siberia and the Far East

如果去除掉常见的无意义词(如 “the”、“in”、“of” 等),检索耗时从几秒缩短到毫秒级别。

优化前检索结果

优化前检索结果

优化后检索结果

优化后检索结果

问题分析

由于索引中没有设置停用词,导致检索词中的常见无意义词(如 “the”, “in”, “of”)被大量存储和匹配。这些词出现频率极高,却没有任何实质意义,导致大量不必要的 CPU 和内存消耗。通过启用停用词过滤,可以有效减少索引大小和检索时间。

测试停用词的使用

可以通过 /_analyze API 来测试停用词的效果,使用 stop 过滤器去除无意义词汇:

POST /_analyze
{
    "tokenizer": "standard",
    "filter": [
        "stop"
    ],
    "text": "in publishing houses of Siberia and the Far East"
}

返回结果(停用词被去除):

{
    "tokens": [
        "publishing",
        "houses",
        "Siberia",
        "Far",
        "East"
    ]
}

停用词的配置

官方停用词列表

Elasticsearch 内置了多种语言的停用词列表,Lucene 项目提供了详细的停用词集合,如以下英文停用词:

static {
    final List<String> stopWords =
        Arrays.asList(
            "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is",
            "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there",
            "these", "they", "this", "to", "was", "will", "with");
    final CharArraySet stopSet = new CharArraySet(stopWords, false);
    ENGLISH_STOP_WORDS_SET = CharArraySet.unmodifiableSet(stopSet);
}

配置自定义分析器

在 Elasticsearch 中,可以通过修改索引的 settings 来定义自定义分析器,并为其添加停用词过滤器。

PUT /my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "whitespace",
          "filter": [ "stop" ]
        }
      }
    }
  }
}

可以通过 stopwords 参数指定停用词列表,支持内置语言值或自定义停用词文件。

自定义停用词过滤器

如果内置的停用词列表不满足需求,可以自定义停用词过滤器。例如,以下配置定义了一个区分大小写的停用词过滤器:

PUT /my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "tokenizer": "whitespace",
          "filter": [ "my_custom_stop_words_filter" ]
        }
      },
      "filter": {
        "my_custom_stop_words_filter": {
          "type": "stop",
          "ignore_case": true,
          "stopwords": [ "and", "is", "the" ]
        }
      }
    }
  }
}

索引配置优化

在实际使用中,可以结合停用词过滤器调整索引配置。例如,下面的索引配置应用了自定义停用词过滤器,并且将 analyzer 设置为 cx_analyzer

{
  "settings": {
    "number_of_shards": 30,
    "number_of_replicas": 0,
    "analysis": {
      "filter": {
        "stop_filter": {
          "type": "stop",
          "ignore_case": true,
          "stopwords": "_english_"
        }
      },
      "analyzer": {
        "cx_analyzer": {
          "tokenizer": "standard",
          "filter": [ "stop_filter" ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
       "digest": {
          "type": "text",
          "analyzer": "cx_analyzer"
      }
    }
  }
}

重建索引及数据迁移

由于 Elasticsearch 的索引是不可修改的(特别是分析器相关配置),因此需要通过以下步骤应用新配置:

  1. 创建新索引:使用新配置创建一个新索引。
  2. 迁移数据:使用 Reindex API 或编写脚本将数据从旧索引迁移到新索引。

使用 Reindex API 将旧索引的数据迁移至新索引:

POST _reindex?slices=20&refresh
{
  "source": {
    "index": "index_v1",
    "size": 5000
  },
  "dest": {
    "index": "index_v2"
  }
}

优化后的检索性能

经过停用词配置后,数据检索性能得到了显著提升:

索引索引大小列表检索时间聚合检索时间
原始索引623.40GB5+ 秒12+ 秒
停用词优化后的新索引460.95GB1.06 秒1.23 秒

优化后的检索性能

停用词对性能的提升

停用词是指那些在文本中出现频率较高、但对搜索意义较小的词汇,例如 “the”、“is”、“a” 等。在建立索引时,通过忽略这些词可以减少索引体积,并加快查询速度。

  1. 减少索引体积:外文数据中包含大量无关的停用词,这些词汇如果被索引,会产生大量冗余信息。排除停用词后,索引体积显著缩小。
  2. 减少倒排索引的计算:每次查询时,Elasticsearch 都会通过倒排索引查找相关文档。停用词的高频率出现会增加计算量。排除停用词后,查询时可以跳过这些无意义的文档筛选和打分操作,从而提高效率。
  3. 提高查询相关性:去除停用词后,查询集中在有意义的词汇上,结果更加相关。
  4. 减少聚合计算量:在聚合操作中,停用词如果被索引,可能导致无意义的分组和计算。移除它们后,聚合性能大幅提升。

http://www.kler.cn/news/314823.html

相关文章:

  • 【补充篇】Davinci工具要求的dbc格式
  • Springboot与minio
  • 【百日算法计划】:每日一题,见证成长(016)
  • [数据集][目标检测]文本表格检测数据集VOC+YOLO格式6688张5类别
  • 华为HarmonyOS地图服务 3 - 如何开启和展示“我的位置”?
  • 掌控历史:如何通过Git版本管理工具提升你的开发效率
  • 【记录一下VMware上开虚拟端口映射到公网】
  • 华为云centos7.9按装ambari 2.7.5 hostname 踩坑记录
  • SpringBoot中基于Mybatis-Plus多表联查(无xml,通过注解实现)
  • 车载软件调试工具系列---Trace32简介UI界面简介
  • C#基础(16)实践:学生成绩管理系统
  • 1.随机事件与概率
  • TCP: Textual-based Class-aware Prompt tuning for Visual-Language Model
  • 【学习笔记】STM32F407探索者HAL库开发(四)F103时钟系统配置
  • 等保测评与网络安全等级划分
  • 【网络通信基础与实践第三讲】传输层协议概述包括UDP协议和TCP协议
  • linux 基础(一)mkdir、ls、vi、ifconfig
  • 汽车EDI:MöllerTech EDI项目案例
  • 实战讲稿:Spring Boot整合MyBatis
  • 前端入门:HTML+CSS简便开发的技巧
  • 美国火箭实验室Rocket Lab USA(RKLB)
  • Tomcat窗口运行修改窗口标题显示项目日期时间
  • 【开源免费】基于SpringBoot+Vue.JS教师工作量管理系统(JAVA毕业设计)
  • 【微服务】Eureka的自我保护机制
  • (学习记录)使用 STM32CubeMX——配置时钟(入门)
  • 基于Windows系统以tomcat为案例,讲解如何新增自启动服务,定时重启服务。
  • mybatis 和 mybatis-plus
  • mysql批量修改表前缀
  • 【java实现json转化为CSV文件】
  • 【C++二叉树】二叉树的前序遍历、中序遍历、后序遍历递归与非递归实现