Elasticsearch同义词最佳实践

        毫无疑问,使用同义词是搜索工程师工具箱中最重要的技巧之一。尽管新手有时会低估同义词的重要性,但几乎所有搜索系统都离不开它。与此同时,人们有时仍会低估与使用同义词相关的一些复杂情况和微妙情形,甚至高级用户也不例外。

        用好同义词库,在搜索的过程中,在提升召回率上,有着奇迹般的力量。

        最近正在做同义词库的工作,在提升召回效果方面,确实有很大的贡献。本篇文章中,将会详细讲解如何使用,其中的坑,以及各种玩法的最佳实践。本篇博文还会回答一些有关同义词使用方法的常见问题,并指出一些经常需要注意的相关事项。

同义词库使用需求

  1. 提升召回率。提升召回效果。
  2. 词库热更新需求。

前言、为什么要使用同义词

这里引用官方博文的描述。

为帮助大家理解同义词的巨大作用和灵活性,我们来快速看一下当今大多数搜索引擎的内在工作原理。搜索引擎会对文档和查询进行分析并将其拆解为最小的单元(通常称为词元,实际上就是抽象的符号)。搜索时,匹配过程会使用简单字串相似度,所以如果查询中有一些十分微小的拼写错误(例如“hous”,只比“house”少一个字母 e)或者使用名词的复数形式(“houses”),即使文档中包含名词的单数形式(“house”),搜索引擎也不会匹配到这份文档。词干提取器或模糊查询等工具虽然可以解决一些最常见的此类问题,但是它们并不能消除相关联的概念或想法之间的差异,也不能将文档或查询中稍有不同的单词用法视为等同。 这时同义词就派上了大用场。同义词的英文 synonym 来自于希腊语,分别是前缀 σύν(syn,表示“一起”)和 ὄνομα(ónoma,表示“名称”)。从它的词源可以看出,同义词表示的是在同一语言或领域中具有完全或基本相同意思的不同词语。实际上,同义词的范围非常广泛,包括一般同义词(“疲劳”和“困倦”)、缩写(英镑的两种写法“lb.”和“pound”)、电商搜索中产品的不同拼写(“iPod”和“i-Pod”)、细微的语言差异(例如均表示电梯的英式英语“lift”和美式英语“elevator”)、专业用词和普通用词(例如“犬”和“狗”),甚至单纯表示同一概念的两种方式(“宇宙”和“太空”)。通过提供恰当的同义词规则,搜索工程师能够就哪些词在各自领域内具有相似意思并应该采取相似处理方法提供相关信息。 对搜索引擎而言,至为重要的是知道文档中的哪个字词与查询内容相匹配,即使它们可能看起来并不一样。由于这涉及到十分具体的领域知识,所以用户需要提供恰当的规则。同义词筛选器可在定制分析器中使用,其能够基于用户定义的规则替换或添加其他词元,既可在索引时进行以便在索引后的文档中同时存储这些内容(例如词语的两种变体),也可在索引时进行以扩展搜索词并匹配到更多相关文档。我们稍后会讨论这两种方法的优缺点。

官方的描述,总是很晦涩。其实很简单,就是要解决我在本文开头写的两个需求点。

一、关于同义词最佳实践问题

  1. 如何用好同义词?

关于这个问题,其实应该清楚它的工作原理。这里举个例子,一篇文章中,用来描述被包围了,可以用八方受敌,也可以用四面楚歌来描述。再结合ES的内部存储原理,我们可以选择在索引阶段,在文章中遇到八方来敌的时候,会在倒排表中添加八方来敌和四面楚歌这两个词,文档id指向同一个。这个过程是同义词在索引阶段生效。

但是在索引阶段生效,有很大的弊端。

  • 由于必须对所有同义词进行索引,所以索引规模会变大。整体存储空间增加一倍甚至是几倍。这在超大规模的集群中使用,绝对是无法接受的。想想300个节点的集群,增加一倍或者两倍,老板绝对不会同意
  • 搜索得分(依赖于字词统计数据)可能会受影响,因为同义词也会计算在内,所以不常见单词的统计数据会存在偏差。这里和BM25相关性分数有关,以为词频会发生很大的变化。
  • 同义词库无法动态更新,除非进行重新索引,否则无法针对既有文档更改同义词规则。在超大规模的集群中,更新一下词库,重跑一遍数据,绝对不是一天两天能完成的,动辄上月。

同义词还可以在搜索阶段生效。这可以完美的解决以上在索引阶段生效的三个致命 的问题。其工作原理,理解起来也很容易,就是在搜索阶段中的分词的时候,匹配一下同 义词。例如一次搜索中搜了八方受敌,但是,实际上逻辑是这样的 (八方受敌 OR 四面 楚歌)。同样,这样做也是有代价的。它无法很大的应对超多关键词的检索。假如你的一 次搜索 100个关键词。经过同义词以后,有可能变成 200个甚至更多关键词。

  • 检索过程中的性能损失。如果本身检索的关键词不多,那影响微乎其微。假如本来检索关键词就很多,又开启同义词,性能损失绝对会在一倍以上!!!即使是这样,在搜索阶段使用同义词,也远好于在索引阶段使用同义词。
  • 检索关键词变多。检索的过程中,花费的资源也会更多。这点主要体现在CPU上。

但是在搜索阶段使用同义词。它是能够解决同义词库更新的需求的。统一词库可以随 时变动。而这个更新成本,并不大。对于7.3版本以后的ES来说,仅仅是触发一次reloadApi的事情。

POST my_index/_reload_search_analyzers

返回信息如下:

{"_shards" : {"total" : 3,"successful" : 3,"failed" : 0},
  "reload_details" : [{"index" : "my_index","reloaded_analyzers" : ["synonym_analyzer" # 这里是我定义的带有同义词的分词器。
      ],"reloaded_node_ids" : ["jiIC9zJyTES_dMIw0w6n8A","dMKuVhnvQySXkO7AfZCXrA","_6o86PMrRlegvJfB_G8bTw"
      ]}
  ]
}

    1. 同义词库的格式问题

ES中,同义词库可以有不同的格式。这里也有很多妙用!我举三个例子

  • eg1 :上班 => 工作 干活
  • eg2 :高兴,快乐,娱乐,兴奋
  • eg3 : 工作 干活 => 上班

其中eg1,他的意思是,把上班,映射成两个词。假如你搜索上班,经过分词器以后,就变成了搜索 工作和干活。这样适合在搜索阶段使用。可以提升召回的数量和质量。

其中eg2,它的意思是,遇到高兴的时候,会分词器会解析成,高兴,快乐,娱乐,兴奋这四个词,同样真正的搜索也是用这四个词去搜索的。这样适合在搜索阶段使用。可以提升召回的数量和质量。

其中eg3,它的意思是,把工作和干活映射成上班。这样的可以应用在索引阶段。其实可以巧妙的帮业务去解决归一化的问题。假如中国,cn,zh,chaina,中华人民共和国,都想映射成中国,做标准化的数据,在检索阶段是可以提速的。同样在索引阶段也是可以节省倒排链的长度的。

二、实战

实际操作一下。

  1. 是否使用插件?

同义词其实是ES本身就有的能力。同义词插件,通常是用来做热更新的,或者是用来把词库放在远端(例如Nginx)。其实本质上是解决更新问题的。假如说你的集群有几百个节点,用本地词库,每次更新词库要更新几百个节点,这操作起来多少有点麻烦。

  1. 如何使用同义词?

在es里边其实使用的是filter,添加一个filter即可,并把这个filte在分词器中绑定。

Synonym token filter | Elasticsearch Guide [7.11] | Elastic

我这里只提几个点。

PUT /test_index
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "synonym": {
            "tokenizer": "whitespace",# 这里引用了同义词的filter
            "filter": [ "synonym" ]
          }
        },
        "filter": {
          "synonym": {
            "type": "synonym",# 注意这里,analysis一个目录,它是在es解压后的config下的目录。synonym.txt 是同义词库。具体文件,下边会给。
            "synonyms_path": "analysis/synonym.txt",# 这个参数,可以忽略同义词库中分词有问题的错误行。
             "lenient": true,  # 这个参数很重要,只有开其他,才能实现同义词库的热更新。
            "updateable": true
          }
        }
      }
    }
  }
}

  1. 同义词库

https://github.com/zhoushineyoung/search-prod/blob/63dba77eaa98a81e29b9ac8e9179ac5b93538da3/solr-cloud/solr-4.7.0/solr/sentiment/conf/synonyms.txt#L1981

这里分享了一个同一个以词库。请注意词库的内容。根据上述如何修改词库,自行决定。我是把同义词用逗号分隔的。我把这个文件中的 => 替换成了逗号。

  1. 如何动态更新

POST article_info_test_1109_2/reload_search_analyzers
# 执行结果
{"_shards" : {"total" : 3,"successful" : 3,"failed" : 0},"reload_details" : [{"index" : "article_info_test_1109_2",# 这里可以看到有刷新的分词器。"reloaded_analyzers" : ["synonym_analyzer"],"reloaded_node_ids" : ["jiIC9zJyTES_dMIw0w6n8A","dMKuVhnvQySXkO7AfZCXrA","_6o86PMrRlegvJfB_G8bTw"]}]
}

三、同义词官方博文

借助同义词让 Elasticsearch 更加强大 | Elastic Blog

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

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

相关文章

复杂数据统计与R语言程序设计实验二

1、创建一个对象,并进行数据类型的转换、判别等操作,步骤如下。 ①使用命令清空工作空间,创建一个对象x,内含元素为序列:1,3,5,6,8。 ②判断对象x是否为数值型数据。 ③…

OpenGL 的学习之路-4(变换)

三大变换:平移、缩放、旋转(通过这三种变换,可以将图像移动到任意位置) 其实,这背后对应的数学在 闫令琪 图形学课程 中有过一些了解,所以,理解起来也不觉得很困难。看程序吧。 1.画三角形&am…

OpenCV入门2——图像视频的加载与展示一些API

文章目录 题目OpenCV创建显示窗口OpenCV加载显示图片题目 OpenCV保存文件利用OpenCV从摄像头采集视频从多媒体文件中读取视频帧将视频数据录制成多媒体文件OpenCV控制鼠标关于[np.uint8](https://stackoverflow.com/questions/68387192/what-is-np-uint8) OpenCV中的TrackBar控…

初试 jmeter做压力测试

一.前言 压力测试是每一个Web应用程序上线之前都需要做的一个测试,他可以帮助我们发现系统中的瓶颈问题,减少发布到生产环境后出问题的几率;预估系统的承载能力,使我们能根据其做出一些应对措施。所以压力测试是一个非常重要的步…

mac无法向移动硬盘拷贝文件怎么解决?不能读取移动硬盘文件怎么解决

有时候我们在使用mac的时候,会遇到一些问题,比如无法向移动硬盘拷贝文件或者不能读取移动硬盘文件。这些问题会给我们的工作和生活带来不便,所以我们需要找到原因和解决办法。本文将为你介绍mac无法向移动硬盘拷贝文件怎么回事,以…

CTFSHOW 文件上传

web151 JS前端绕过 直接上传 png的图片马 然后抓包修改为php asystem("ls /var/www/html"); asystem("cat /var/www/html/flag.php"); web152 和151一样的方法也可以实现上传 asystem("ls /var/www/html"); asystem("cat /var/www/html…

Anaconda的安装使用及pycharm设置conda虚拟环境

1.python和包以及anaconda的概念关系 python “工人” 包 “工具” 环境 “工具箱” anaconda “放很多工具箱的大箱子” python等于工人这个好理解,就是编程需要用python来实现对应功能,即工人完成某项工程。 包等于工具,就是工人…

YOLOv8-Seg改进:轻量级Backbone改进 | VanillaNet极简神经网络模型 | 华为诺亚2023

🚀🚀🚀本文改进:一种极简的神经网络模型 VanillaNet,支持vanillanet_5, vanillanet_6, vanillanet_7, vanillanet_8, vanillanet_9, vanillanet_10, vanillanet_11等版本,相比较yolov8-seg各个版本如下: layersparametersgradientsGFLOPsvanillanet_521230017523

Excel vlookup 如何使用

Excel vlookup 如何使用 打开WX, 搜索 “程序员奇点” Excel vlookup可以说是利器,非常好用的工具,用来查询 Excel 或者进行数据匹配,十分方便。 VLookuP 如何使用,不常用的同学经常容易忘记,这次做个记录&#xff…

【Python自动化】定时自动采集,并发送微信告警通知,全流程案例讲解!

文章目录 一、概要二、效果演示三、代码讲解3.1 爬虫采集行政处罚数据3.2 存MySQL数据库3.3 发送告警邮件&微信通知3.4 定时机制 四、总结 一、概要 您好!我是马哥python说,一名10年程序猿。 我原创开发了一套定时自动化爬取方案,完整开…

Flutter笔记:桌面应用 窗口定制库 bitsdojo_window

Flutter笔记 桌面应用窗口管理库 bitsdojo_window 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/13446…

cesium 重点区域大屏展示效果(加载行政区划)

cesium 重点区域大屏展示效果(配色不太好看,主要看思路和方法) 1、实现思路(文张最后有**源码 **) 1、第一步将cesium背景调成透明关掉光照大气等效果相关属性都在“viewer.scene”中 2、第二步添加背景图片此背景图片直接用html加css就可以完成 3、第三步添加蒙版效果也…

【一周安全资讯1118】北京高院发布《侵犯公民个人信息犯罪审判白皮书》;工银金融勒索案的事件响应服务商MoxFive是谁?

要闻速览 1、工信部等四部门部署开展智能网联汽车准入和上路通行试点工作 2、北京高院发布《侵犯公民个人信息犯罪审判白皮书》 3、丰田公司确认遭遇美杜莎勒索软件攻击 4、家中设备把数据信息泄露到国外,浙江一男子被罚5000元 5、工银金融勒索案的事件响应服务商M…

计算机算法分析与设计(23)---二分搜索算法(C++)

文章目录 1. 算法介绍2. 代码编写 1. 算法介绍 1. 二分搜索(英语:binary search),也称折半搜索(英语:half-interval search)、对数搜索(英语:logarithmic search&#xf…

linux系统中安装redis到指定目录

linux系统中安装redis到指定目录 下载要求版本的redis源码包 上传并解压redis源码包 # 在/opt/app目录下创建redis解压安装目录 cd /opt/app mkdir redis# 切换到解压目录下 cd /opt/app/redis# 解压 tar -zxvf redis-2.8.17.tar.gz编译安装 # /opt/app/redis路径下,进入re…

Spring Cloud GateWay简介

什么是网关 网关是一种充当转换重任的计算机系统或设备,使用在不同的通信协议、数据格式或语言,甚至网关是一种充当转换重任的计算机系统或设备,使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间进行数…

Git命令总结-常用-后续使用频繁的再添加~

Git命令总结-常用 久了不用,有些时候老是会忘记一些命令,多的都记录一下,方便查找 git init 初始化一个Git仓库,执行完git init命令后,会生成一个**.git**目录,该目录包含了资源数据,且只会在…

vite+react+typescript 遇到的问题

1.找不到模块“vite”。你的意思是要将 “moduleResolution” 选项设置为 “node”,还是要将别名添加到 “paths” 选项中 tsconfig.json 中 compilerOptions:{“moduleResolution”: node} 2.未知的编译器选项“allowImportingTsExtensions” 该选项用于控制是否…

【C++函数的进化】函数指针,模板,仿函数,lambda表达式

/*** poject * author jUicE_g2R(qq:3406291309)* file C函数的进化* * language C* EDA Base on VS2022* editor Obsidian(黑曜石笔记软件)* * copyright 2023* COPYRIGHT 原创学习笔记:转载需获得博…

Unity Quaternion接口API的常用方法解析_unity基础开发教程

Quaternion接口的常用方法 Quaternion.Euler()Quaternion.Lerp()Quaternion.Inverse()Quaternion.RotateTowards() Quaternion在Unity中是一种非常重要的数据类型,用于表示3D空间中的旋转。Quaternion可以表示任何旋转,无论是在哪个轴上旋转多少度&#…