Elasticsearch Suggesters API详解与联想词自动补全应用

news2024/11/19 17:50:39

Elasticsearch Suggesters API详解与联想词自动补全应用

  • 引言
  • Elasticsearch Suggesters
    • 1. Term Suggester
      • 实现步骤
      • 示例
    • 2. Phrase Suggester
      • 示例
    • 3. Completion Suggester
      • 创建映射和插入数据
      • 查询示例
    • 4. Context Suggester
      • 示例
  • Completion Suggester
    • 1. 工作原理
    • 2. 使用流程
    • 3. 使用建议和优化
    • 4. 单节点使用优化

引言

在现代搜索引擎的应用场景中,自动补全和拼写检查已成为提升用户搜索体验的重要功能Elasticsearch 作为一款广泛使用的分布式搜索引擎,提供了丰富的 Suggesters API,可以帮助开发者实现精确的自动补全和拼写纠错功能本文将深入探讨 Elasticsearch 中的四种核心 Suggester——Term SuggesterPhrase SuggesterCompletion SuggesterContext Suggester,并通过实际示例展示如何在不同场景下使用这些工具来优化用户的搜索体验

Elasticsearch Suggesters

参考官网:[Suggesters | Elasticsearch Guide 7.17] | Elastic

1. Term Suggester

Term Suggester 主要用于单个词的拼写纠错它通过编辑距离算法,在用户输入的词不存在于索引中时,提供一系列可能的正确拼写Term Suggester 不仅可以返回建议词,还可以显示每个建议词的得分和词频

实现步骤

  • 创建索引并插入数据:确保索引中存在需要搜索的字段
  • 发送 Suggest 请求:在 Elasticsearch 的 _search 端点发送一个包含 suggest 字段的请求

示例

POST /zhoutest/_search
{
  "suggest": {
    "my_suggestion": {
      "text": "hots vlna",
      "term": {
        "field": "content"
      }
    }
  }
}

在这个例子中,用户输入了错误的短语 hots vlnaTerm Suggester 会建议正确的拼写,比如 hotvolna

2. Phrase Suggester

Phrase Suggester 在 Term Suggester 的基础上更进一步,它可以处理整个短语的拼写纠错Phrase Suggester 考虑了多个词之间的关系,如它们是否同时出现在索引中,以及它们之间的词频和相邻程度

示例

POST /zhoutest/_search
{
  "suggest": {
    "my_suggestion": {
      "text": "lucne and elasticsearch rock",
      "phrase": {
        "field": "body",
        "highlight": {
          "pre_tag": "<em>",
          "post_tag": "</em>"
        }
      }
    }
  }
}

在这个例子中,Phrase Suggester 会识别 lucne 可能是拼写错误,建议改为 lucene,并对其进行高亮显示

3. Completion Suggester

Completion Suggester 专用于快速的前缀搜索和自动补全它通过将分词后的数据编码成 FST(Finite State Transducer)并存储在内存中,以实现极快的查询速度Completion Suggester 非常适用于需要即时反馈的场景,如搜索框的自动补全功能

创建映射和插入数据

首先,需要定义字段类型为 completion 的映射:

PUT localhost:9200/zhoutest/test/_mapping
{
  "test": {
    "properties": {
      "name_suggest": {
        "type": "completion",
        "analyzer": "simple",
        "search_analyzer": "simple",
        "payloads": true
      }
    }
  }
}

接着插入数据:

PUT 'localhost:9200/zhoutest/test/1?refresh=true'
{
  "name": "xdy",
  "name_suggest": {
    "input": ["xdy", "hdu"]
  }
}

查询示例

POST 'localhost:9200/zhoutest/_suggest?pretty'
{
  "index-suggest": {
    "text": "b",
    "completion": {
      "field": "name_suggest"
    }
  }
}

当用户输入 b 时,Completion Suggester 会返回以 b 开头的建议词,如 bananabicycle

4. Context Suggester

Context Suggester 允许基于上下文(如类别或地理位置)提供更精确的建议它能够提高搜索建议的准确性和相关性,适合需要根据用户输入环境来调整建议结果的场景

示例

假设有一个应用程序需要基于用户的地理位置提供建议,可以这样配置 Context Suggester

PUT /zhoutest
{
  "mappings": {
    "properties": {
      "suggest": {
        "type": "completion",
        "contexts": [
          { "name": "location", "type": "geo" }
        ]
      }
    }
  }
}

然后可以插入数据并执行查询,基于用户的地理位置提供更精确的推荐

Completion Suggester

Completion Suggester 是 Elasticsearch 中的一种专用于实现前缀搜索和自动补全功能的 Suggester它通过将数据编码为 FST(有限状态转换器),并将其存储在内存中,从而提供极快的查询速度,非常适用于需要即时反馈的场景,如搜索框的自动补全功能

image-20240829134914853

1. 工作原理

Completion Suggester 的核心是 FST,它是一种压缩的有限状态机,能够快速地匹配前缀并生成补全建议FST 具备以下特性:

  • 前缀匹配:通过编码词汇表中的所有前缀,FST 能够迅速找到与用户输入匹配的前缀并返回相应的候选项
  • 压缩存储:FST 在存储时会自动去除重复前缀,从而显著降低内存占用
  • 即时查询:由于 FST 是内存中操作的,查询速度非常快,能够实时提供搜索建议

2. 使用流程

2.1 创建索引与映射

在使用 Completion Suggester 之前,需要为数据创建索引,并在索引的映射中定义字段类型为 completion可以选择设置 analyzersearch_analyzer 来控制数据如何被分析

示例

PUT /zhoutest
{
  "mappings": {
    "properties": {
      "name_suggest": {
        "type": "completion"
      }
    }
  }
}

2.2 插入数据

定义好索引映射后,可以向索引中插入数据需要确保将希望进行补全建议的字段作为 input 提供给 completion 类型字段

示例

PUT /zhoutest/_doc/1
{
  "name": "Elasticsearch",
  "name_suggest": {
    "input": ["Elasticsearch", "Elastic"]
  }
}

PUT /zhoutest/_doc/2
{
  "name": "Elastic Stack",
  "name_suggest": {
    "input": ["Elastic Stack", "ELK Stack"]
  }
}

在以上示例中,我们为每个文档提供了多个输入选项,用于在用户输入时提供不同的补全建议

2.3 查询建议

插入数据后,可以使用 Completion Suggester 进行查询查询请求会根据用户输入的文本前缀,返回匹配的建议

示例

POST /zhoutest/_search
{
  "suggest": {
    "name_suggestion": {
      "prefix": "Elas",              // 用户输入的前缀
      "completion": {
        "field": "name_suggest",     // 指定补全字段
        "size": 5,                   // 返回的建议数量
        "fuzzy": {                   // 启用模糊搜索,允许拼写错误
          "fuzziness": 2
        }
      }
    }
  }
}

在这个示例中,用户输入了前缀 Elas,Completion Suggester 会返回与该前缀匹配的词汇,如 ElasticsearchElastic Stack

2.4 响应结果

查询结果会返回与输入前缀匹配的建议列表,每个建议包含了补全的文本以及其他元数据(如得分、频率等)

示例

{
  "suggest": {
    "name_suggestion": [
      {
        "text": "Elas",
        "offset": 0,
        "length": 4,
        "options": [
          {
            "text": "Elasticsearch",
            "score": 1.0
          },
          {
            "text": "Elastic Stack",
            "score": 1.0
          }
        ]
      }
    ]
  }
}

3. 使用建议和优化

  • 字段优化:在定义 completion 类型字段时,合理选择分析器和映射配置,可以优化查询的性能和结果质量
  • 模糊匹配:如果需要容忍拼写错误,可以启用 fuzzy 配置,允许模糊匹配提升用户使用
  • 内存使用:由于 FST 存储在内存中,建议在高并发或大规模数据场景下,合理配置内存,以确保系统的稳定性

4. 单节点使用优化

如果在单节点数据量较大并且设置的补全字段较多的时候,可能会导致下列报错:

[ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [test_node1] fatal error in thread [elasticsearch[test_node1][management][T#1]], exiting
java.lang.OutOfMemoryError: Java heap space
        at org.apache.lucene.util.fst.OnHeapFSTStore.init(OnHeapFSTStore.java:59) ~[lucene-core-8.6.2.jar:8.6.2 016993b65e393b58246d54e8ddda9f56a453eb0e - ivera - 2020-08-26 10:53:36]
        at org.apache.lucene.util.fst.FST.<init>(FST.java:461) ~[lucene-core-8.6.2.jar:8.6.2 016993b65e393b58246d54e8ddda9f56a453eb0e - ivera - 2020-08-26 10:53:36]
        at org.apache.lucene.util.fst.FST.<init>(FST.java:412) ~[lucene-core-8.6.2.jar:8.6.2 016993b65e393b58246d54e8ddda9f56a453eb0e - ivera - 2020-08-26 10:53:36]
        at org.apache.lucene.search.suggest.document.NRTSuggester.load(NRTSuggester.java:332) ~[lucene-suggest-8.6.2.jar:8.6.2 016993b65e393b58246d54e8ddda9f56a453eb0e - ivera - 2020-08-26 10:54:46]
        at org.apache.lucene.search.suggest.document.CompletionsTermsReader.suggester(CompletionsTermsReader.java:70) ~[lucene-suggest-8.6.2.jar:8.6.2 016993b65e393b58246d54e8ddda9f56a453eb0e - ivera - 2020-08-26 10:54:46]
        at org.apache.lucene.search.suggest.document.CompletionTerms.suggester(CompletionTerms.java:71) ~[lucene-suggest-8.6.2.jar:8.6.2 016993b65e393b58246d54e8ddda9f56a453eb0e - ivera - 2020-08-26 10:54:46]
        at org.elasticsearch.index.engine.CompletionStatsCache.lambda$get$0(CompletionStatsCache.java:93) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.index.engine.CompletionStatsCache$$Lambda$5243/0x00000008018102e0.get(Unknown Source) ~[?:?]
        at org.elasticsearch.action.ActionListener.completeWith(ActionListener.java:325) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.index.engine.CompletionStatsCache.get(CompletionStatsCache.java:82) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.index.engine.InternalEngine.completionStats(InternalEngine.java:323) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.index.shard.IndexShard.completionStats(IndexShard.java:1073) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.action.admin.indices.stats.CommonStats.<init>(CommonStats.java:207) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.action.admin.indices.stats.TransportIndicesStatsAction.shardOperation(TransportIndicesStatsAction.java:105) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.action.admin.indices.stats.TransportIndicesStatsAction.shardOperation(TransportIndicesStatsAction.java:48) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.action.support.broadcast.node.TransportBroadcastByNodeAction$BroadcastByNodeTransportRequestHandler.onShardOperation(TransportBroadcastByNodeAction.java:423) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.action.support.broadcast.node.TransportBroadcastByNodeAction$BroadcastByNodeTransportRequestHandler.messageReceived(TransportBroadcastByNodeAction.java:401) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.action.support.broadcast.node.TransportBroadcastByNodeAction$BroadcastByNodeTransportRequestHandler.messageReceived(TransportBroadcastByNodeAction.java:388) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor$ProfileSecuredRequestHandler$1.doRun(SecurityServerTransportInterceptor.java:257) ~[?:?]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor$ProfileSecuredRequestHandler.messageReceived(SecurityServerTransportInterceptor.java:315) ~[?:?]
        at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:72) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.transport.TransportService$8.doRun(TransportService.java:800) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:737) ~[elasticsearch-7.9.2.jar:7.9.2]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.9.2.jar:7.9.2]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[?:?]
        at java.lang.Thread.run(Thread.java:832) [?:?]
fatal error in thread [elasticsearch[test_node1][management][T#1]], exiting
java.lang.OutOfMemoryError: Java heap space
        at org.apache.lucene.util.fst.OnHeapFSTStore.init(OnHeapFSTStore.java:59)
        at org.apache.lucene.util.fst.FST.<init>(FST.java:461)

解决方案:

  1. 增加 JVM 堆内存

    • 可以尝试增加 Elasticsearch JVM 的堆内存大小默认情况下,JVM 堆内存的最大值可能较小,可以通过调整 jvm.options 文件中的 -Xmx-Xms 参数来增加堆内存具体的堆内存大小需要根据硬件配置和数据规模来设置,最大修改为:

      -Xms31g
      -Xmx31g
      
  2. 使用es集群配置

    改为使用集群,增加集群数据节点,同时合理划分分片数量,确保数据分片有足够的节点进行分布,可以减轻每个节点的内存负担

    分片配置

    • 分片数量:减少每个索引的主分片数量,同时增加副本分片,以便分布在多个节点上这样可以降低每个节点的内存负担对于大索引,分片的大小通常建议在10GB到50GB之间
    • 分片分配:确保分片均匀分布在集群的所有节点上,以避免单个节点过载

    内存设置

    • JVM堆内存:对于每个节点,JVM堆内存的大小应设置为服务器物理内存的50%左右,但不超过32GB(推荐设置在-Xms-Xmx之间相同的值)
    • 操作系统级别的内存管理:可以配置vm.max_map_count参数,以增加可映射文件数增大file descriptors限制以支持更多的文件句柄

    FST内存占用

    • 减少自动补全字段:由于FST(有限状态转换器)数据结构用于实现自动补全功能,它的内存占用可能很大建议减少自动补全字段的数量或分割这些字段
    • FST外置存储:考虑将FST存储在磁盘上,而不是堆内存中这可以通过适当的索引设置来实现,例如通过调整index.codecbest_compression

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2086988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业级低代码解决方案:JNPF平台深度解析

随着数字化转型的不断推进&#xff0c;企业对于快速开发、高效部署和灵活迭代的需求日益增长。低代码开发平台应运而生&#xff0c;成为加速企业应用开发的重要工具。在众多低代码平台中&#xff0c;JNPF凭借其强大的企业级特性脱颖而出&#xff0c;成为众多企业的首选。本文将…

【系统架构设计师-2019年】综合知识-答案及详解

文章目录 【第1题】【第2~3题】【第4题】【第5题】【第6~7题】【第8题】【第9~10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16~17题】【第18~19题】【第20~21题】【第22~23题】【第24~25题】【第26~28题】【第29~30题】【第31~32题】【第33题】【第34题】【第…

Java中三大容器类(List、Set、Map)详解

三大容器介绍 名称结构特点常见实现类List&#xff08;列表&#xff09;由有序的元素序列组成&#xff0c;可以包含重复元素可以通过索引访问元素&#xff0c;插入的顺序与遍历顺序一致ArrayList、LinkedList、VectorMap&#xff08;映射&#xff09;由键值对(Key-Value)组成的…

Axure 9 使用

一、界面初识 二、基础功能 1.菜单栏 1.1文件 新建文件&#xff1a;axure9包含四种文件.rp代表原型文件&#xff0c;.rplib代表元件库文件&#xff0c;.rpteam 团队项目文件 .html 网页文件 偏好设置&#xff1a;备份&#xff0c;需要备份文件再从备份中恢复 创建项目团…

GPT-SoVITS:零样本语音合成AI

GPT-SoVITS 是一种语音合成模型&#xff0c;于 2024 年 2 月 18 日发布。它支持使用参考音频进行零样本语音合成&#xff0c;并且可以进行微调以提高性能。 GPT-SoVITS 的功能特性包括&#xff1a; Zero-Shot TTS&#xff1a;零样本语音合成&#xff0c;输入 5 秒音频样本即可…

57.基于IIC协议的EEPROM驱动控制(4)

&#xff08;1&#xff09;顶层代码&#xff1a; module IIC_EEPROM(input wire clk ,input wire reset_n ,input wire key_r ,input wire key_w ,output wire …

DM一主一实时备一异步备守护集群安装

在前面章节中已经部署了一主一实时备机&#xff0c;此次实施过程中主要添加异步备库。 1. 环境描述 实例详情&#xff1a; 端口详情 2. 关闭主备库守护进程、监视器、数据库实例 [dmdbaray1 ]$ DmWatcherServiceDW stop Stopping DmWatcherServiceDW: …

基于ssm+vue+uniapp的图书管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

JVM 内存参数

文章目录 引言I JVM基础知识Java 语言是解释型的OpenJDK和Sun/Oracle JDK和hotspot的关系JDK、JRE、JVM 之间的关系JVM基础功能JVM组成JIT:Just In Time CompilerJVM内存区域JVM运行时数据区JVM 堆内存布局II JVM 内存参数常用参数JIT编译参数GC信息打印GC参数III 例子引言 J…

M2BEV

Part 1: 2D 图像编码器 给定 NNN 张大小为 HW3的图像&#xff0c;我们对所有图像使用共享的 CNN 主干网络进行前向传播&#xff0c;例如使用 ResNet&#xff0c;并通过特征金字塔网络&#xff08;FPN&#xff09;创建四级特征 F1,F2,F3,F4。 然后&#xff0c;将这些特征全部上…

Quartus网盘资源下载与安装 附图文安装教程

如大家所了解的&#xff0c;Quartus是一种FPGA设计软件&#xff08;相信理工科的小伙伴&#xff0c;很多都接触或学习过FPGA&#xff09;&#xff0c;旨在为数字电路设计师提供一个高效、便捷的开发环境。它可以帮助用户完成数字逻辑电路的设计、仿真、综合和布局&#xff0c;以…

webpack4手动搭建Vue项目

小满视频 很多解释使用通义灵码搜的,通义灵码的搜索结果也是有错误的全程使用pnpm包管理工具&#xff0c;和npm的用法基本一样 学习总结 1. 多看看webpack官网 2. webpack的作用&#xff1a;配置一堆东西&#xff0c;达到运行程序的目的 3. 无论什么东西都转成js&#xff0c;…

什么是CSRF跨站请求伪造

CSRF&#xff08;跨站请求伪造&#xff0c;Cross-Site Request Forgery&#xff09;是一种网络攻击&#xff0c;攻击者通过伪造用户的身份&#xff0c;诱使用户在已认证的 Web 应用上执行非预期的操作。CSRF 攻击的风险在于它能够利用用户的身份认证状态&#xff0c;从而执行恶…

app逆向1-实战里常见东西

幕布链接&#xff1a;app逆向1-实战里常见东西 - 幕布

JVM性能监控实用工具jconsole与jvisualvm

jdk小工具jconsole与jvisualvm&#xff0c;jvisualvm为升级版的jconsole&#xff1b;通过命令行启动&#xff0c;可监控本地和远程应用。 推荐使用&#xff1a;jvisualvm jconsole使用 1.直接命令 jcondole 打开窗口&#xff0c;选择我们要查看的进行 连接后可看到面板 jvisu…

4岁患儿玩耍误伤眼内起迷“障”,耽误多年成都爱尔公益救助手术焕清晰

近日&#xff0c;成都爱尔眼科医院收治了一名来自西藏的7岁小患者小多。小多是由父亲带到医院的&#xff0c;可惜两人都不会汉语&#xff0c;医护人员与他们的交流依靠着孩子父亲拨打的亲戚电话&#xff0c;在电话中一句一句的翻译终于厘清病情原委。 据说&#xff0c;3年前小多…

固态硬盘损坏,有什么方法可以恢复数据?

我认为值得推荐的固态硬盘数据恢复&#xff0c;必须满足2个硬条件&#xff1a; 恢复成功率高 不损害原文件&#xff0c;保证数据的绝对安全 推荐2个超好用的U盘数据恢复神器&#xff0c;帮你快速找回重要文件&#xff01; 1、转转数据恢复大师 点击直达链接>>www.huifuz…

简单工作流-节点增加输入内容

之前已经做完了前端的流程图像绘制&#xff0c;后端对流程图像的CURD&#xff0c;现在主要做流程节点的必要属性做完善&#xff0c;之前只做了节点上权限用户的绑定没有对用户输入内容做管理&#xff0c;现在加上了输入内容管理&#xff0c;具体代码在github上&#xff1a; 前端…

css-50 Projects in 50 Days(1)

改变背景图 html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>改变背景</title><link …

【ceph学习】rgw网关进程如何启动

rgw 网关进程启动 主要在rgw_main.cc的main函数中&#xff0c;主要涉及一些关键线程启动、前端服务器&#xff08;beast等&#xff09;启动、后端存储模块启动&#xff08;rados&#xff09;、perf和log启动等。 流程图关键节点如下&#xff1a; 1、beast的启动 2、rados的启…