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

news/2024/12/23 6:18:21/

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.ppmy.cn/news/1528746.html

相关文章

【Elasticsearch系列四】ELK Stack

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

dbt compile 命令及应用

编写dbt模型和存储过程有较大差异&#xff0c;比如不建议update和insert&#xff0c;大多数代码是select语句。同时需要引用jinja函数、复杂逻辑以及宏&#xff0c;这些差异经常让开发者不确定生成的模型是否满足需求。本文介绍dbt compile命令可以在开发过程中随时查看编译后的…

【毕业设计】基于 PHP 开发的社区交流系统

基于 PHP 开发的社区交流系统可以是一个论坛、博客平台或是问答网站等形式的在线平台&#xff0c;用于用户之间的互动交流。以下是一个简单的 PHP 社区交流系统的示例&#xff0c;包括用户注册、登录、发布帖子、回复帖子等功能。 技术栈 前端&#xff1a;HTML, CSS, JavaScr…

『功能项目』QFrameWorkBug修改器界面【65】

我们打开上一篇64QFrameWork道具栏物品生成的项目&#xff0c; 本章要做的事情是做一个道具bug调试面板&#xff0c;可以增加主角属性&#xff0c;可以增加道具的功能 首先创建一个空物体&#xff08;钉子&#xff09; 按住Alt键将空物体钉到左侧 重命名为Left 创建Button、Im…

基于Python实现一个浪漫烟花秀

为了实现一个类似烟花秀的效果&#xff0c;我们可以通过复杂的粒子系统来模拟烟花的升起、绽放和下落效果。以下是一个示例&#xff0c;旨在创建更为动态和逼真的烟花秀效果。 示例代码 这个代码示例将使用 matplotlib 和 numpy&#xff0c;并实现更丰富的视觉效果&#xff1…

Qt 常用数据类型

目录 Qt 常用数据类型1. 基础类型1. 1 基础数据类型详细说明 1.2 字符串和文本处理详细说明1.3 日期和时间详细说明 1.4 数学和几何详细说明 1.5 颜色和图形详细说明 1.6 数据结构详细说明 1.7 文件 IO 操作和 JSON 解析详细说明 1.8 本地化和国际化详细说明 1.9 网络编程和 UR…

小程序与APP的区别

目录 前言1. 开发方式与成本2. 运行环境与获取途径3. 功能复杂度与交互体验4. 更新与维护5. 推广与用户获取6. 占用空间与存储7. 可分享性总结 前言 小程序与APP作为两种不同类型的应用程序&#xff0c;它们在多个方面存在明显的区别。以下是对这些区别的详细阐述&#xff1a;…

【监控】【Nginx】使用 Prometheus + Grafana 监控 Nginx

目录 一、什么是 Prometheus 和 Grafana&#xff1f;二 、准备工作步骤 1&#xff1a;安装 Prometheus1. 下载并解压 Prometheus2. 编辑 Prometheus 配置&#xff08;prometheus.yml&#xff09;3. 启动 Prometheus 步骤 2&#xff1a;安装 Grafana1. 安装 Grafana2. 启动 Graf…