首页 > 其他分享 >Elasticsearch实战 | match_phrase搜不出来,怎么办?

Elasticsearch实战 | match_phrase搜不出来,怎么办?

时间:2023-08-21 17:44:36浏览次数:33  
标签:检索 max ik Elasticsearch phrase 分词 match

1、问题抛出

某个词组在Elasitcsearch中的某个document中存在,就一定通过某种匹配方式把它搜出来。
举例:

title=公路局正在治理解放大道路面积水问题。

输入关键词:道路,能否搜索到这个document呢?
实际应用中可能需要:
1)检索关键词”理解”、”解放”、”道路”、“理解放大”,都能搜出这篇文档。
2)单个的字拆分“治”、“水”太多干扰,不要被检索出来。
3)待检索的词不在词典中,也必须要查到。
4)待检索词只要在原文title或content中出现,都要检索到。
5)检索要快,要摒弃wildcard模糊匹配性能问题。

2、问题分析

常用的stand标准分词,可以满足要求1)、3)、4)、5)。
标准分词器是什么鬼?
标准分析仪是默认分析仪,如果没有指定,则默认使用该分词器。 它提供了基于语法的标记,并且适用于大多数语言。
对于中文字符串,会逐个汉字分词。
标准分词器的结果如下:

GET /ik_index/_analyze?analyzer=standard
{
"text":"公路局正在治理解放大道路面积水问题"
}
公,路,局,正,在,治,理,解,放,大,道,路,面,积,水,问,题
 

但,会出现冗余数据非常多。
针对要求2),排除match检索,排除stand分词。
针对要求5),排除wildcard模糊检索。
针对要求3)、4),新词也要被检索到比如:“声临其境”、“孙大剩”等也要能被搜索到。
针对要求1),采用match_phrase貌似靠谱些。

3、小试牛刀

先使用IK-max-word细粒度分词器,结合match_phrase试一试?

步骤1:定义索引和Mapping

PUT ik_index
{"mappings":{"ik_type":{"properties":{"title":{"type":"text","fields":{"ik_my_max":{"type":"text","analyzer":"ik_max_word"},"ik_my_smart":{"type":"text","analyzer":"ik_smart"},"keyword":{"type":"keyword","ignore_above":256}}}}}}}

这里,为了验证分词,同时使用了ik_smart和ik_max两种分词。
实际开发中不需要,因为:两种分词共存,会导致导入数据创建索引的时候,索引会非常大,对磁盘和检索性能都会有影响。

步骤2:插入文档

POST ik_index/ik_type/3
{"title":"公路局正在治理解放大道路面积水问题"
}

步骤3:实施检索

POST ik_index/ik_type/_search
{"profile":"true","query":{"match_phrase":{"title.ik_my_max":"道路"}}
}

搜索结果如下:
无结果返回。

{"took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"failed": 0},"hits": {"total": 0,"max_score": null,"hits": []}
}

为什么使用了max_word细粒度分词,使用了match_pharse检索,为什么没有结果。
分析一下:
细粒度ik_max_word分词结果为:

GET /ik_index/_analyze?analyzer=ik_max_word
{
"text":"公路局正在治理解放大道路面积水问题"
}
公路局 ,公路 ,路局 ,路 ,局正 ,正在 ,正 ,治理 ,治 ,理解 ,
理 ,解放 ,解 ,放大 ,大道 ,大 ,道路 ,道 ,路面 ,路 ,
面积 ,面 ,积水 ,积 ,水 ,问题

以上方式,除了可以返回分词结果外,还能返回词所在的位置position。

构建索引的时候,道路被拆分为:道路:16,道:17,路:19。(注意中间加了18:路面)

{"token": "路面","start_offset": 11,"end_offset": 13,"type": "CN_WORD","position": 18}

而检索的时候,而道路拆分为: 道路0 道1 路2

match_phrase检索时候,文档必须同时满足以下两个条件,才能被检索到:
1)分词后所有词项都出现在该字段中;
2)字段中的词项顺序要一致。
位置信息可以被存储在倒排索引中,因此 match_phrase 查询这类对词语位置敏感的查询, 就可以利用位置信息去匹配包含所有查询词项,且各词项顺序也与我们搜索指定一致的文档,中间不夹杂其他词项。

为了验证如上的解释,新增一篇“道路”相关的title,检验一下:

POST ik_index/ik_type/4
{"title":"党员干部坚持走马克思主义道路的重要性"
}

注意:这时,搜索道路是可以匹配到的。

  "hits": {"total": 1,"max_score": 1.9684901,"hits": [{"_index": "ik_index","_type": "ik_type","_id": "4","_score": 1.9684901,"_source": {"title": "党员干部坚持走马克思主义道路的重要性"}}]},

细粒度ik_max_word分词结果为:

党员干部, 党员, 干部, 坚持走, 坚持, 坚, 持, 走马, 马克思主义, 马克思,
马克, 马, 克, 思, 主义, 道路, 道, 路, 重要性, 重要,
要性, 性

构建索引的时候,道路被拆分为:15,16,17位置。
与检索的词项顺序是一致的。
这里解析更详细:http://t.cn/R8pzw9e

4、match_pharse都搜不出来,还有没有别的方案?

有,和match_pharse类似,不过match_phrase_prefix支持最后一个term前缀匹配。
除了把查询文本的最后一个分词只做前缀匹配之外,match_phrase_prefix和match_phrase查询基本一样,参数 max_expansions 控制最后一个单词会被重写成多少个前缀,也就是,控制前缀扩展成分词的数量,默认值是50(官网文档建议50)。
扩展的前缀数量越多,找到的文档数量就越多;
如果前缀扩展的数量太少,可能查找不到相应的文档,遗漏数据。

POST ik_index/ik_type/_search

{

"profile":"true","query":{"match_phrase_prefix" : {"title.ik_my_max" : {"query": "道路","max_expansions": 50}}
}
}

经验证: 关键词”理解”、”解放”、”道路”、“理解放大”,都能搜出这篇文档。

5、应用场景

我们自己开发搜索引擎的时候,经常会出现基于title或者content字段进行检索。
如果用match检索,会出现噪音很多的情况;
如果用match_phrase,会出现某些字段检索不出来的情况,如上分析的“道路”;
如果用wildcard,能检索出来,但又有性能问题的存在。
这时候,可以考虑下: match_phrase_prefix。

6、小结

实际开发中,根据应用场景不同,采用不同的分词器。
如果选用ik,建议使用ik_max_word分词,因为:ik_max_word的分词结果包含ik_smart。
匹配的时候,如果想尽可能的多检索结果,考虑使用match;
如果想尽可能精确的匹配分词结果,考虑使用match_phrase;
如果短语匹配的时候,怕遗漏,考虑使用match_phrase_prefix。

标签:检索,max,ik,Elasticsearch,phrase,分词,match
From: https://www.cnblogs.com/fxr320/p/17646659.html

相关文章

  • 记:Elasticsearch 的 告警机制 和 jvm 内存分配
    Elasticsearch的告警机制导致的更新失败问题总结:由于测试环境资源占用比例过高导致elasticsearch触发保护机制,导致的更新失败的问题Es告警日志:查看服务器资源使用情况:此时Es所在的挂载磁盘已经占用了95%,Es默认的保护机制:属性名属性值(可配置为固定值)含义保......
  • 深入了解Elasticsearch搜索引擎篇:倒排索引、架构设计与优化策略
    什么是倒排索引?有什么好处?倒排索引是一种用于快速检索的数据结构,常用于搜索引擎和数据库中。与传统的正排索引不同,倒排索引是根据关键词来建立索引,而不是根据文档ID。倒排索引的建立过程如下:首先,将每个文档拆分成一系列的关键词或词项,然后建立一个词项到文档的映射。对每个关键......
  • 解密Nginx与Elasticsearch的协同高效:深入理解反向代理与全文搜索
    在当今高度互联的网络环境中,后端技术的结合与优化对于构建高性能应用至关重要。本篇博客将聚焦于两个关键主题:Nginx反向代理和Elasticsearch全文搜索,通过深入分析实现原理和代码示例,展示它们如何协同工作以提升系统性能。Nginx反向代理的作用Nginx不仅仅是一款高性能的Web服务器,还......
  • 构建高性能后端:探秘Nginx与Elasticsearch的技术协同
    在如今的信息时代,高性能的后端技术对于应用的成功至关重要。本文将深入探讨两个关键技术领域:Nginx反向代理和Elasticsearch全文搜索。通过详细的原理解析和实际代码示例,揭示它们如何协同工作,为应用的性能和效率提供强大支持。Nginx反向代理:背后的原理Nginx不仅是一款优秀的Web服务......
  • Nginx与Elasticsearch:高性能后端的黄金组合
    在追求高性能的后端开发中,Nginx与Elasticsearch是两个不可或缺的技术利器。本文将深入剖析这两者,探讨它们的协同作用,通过深入原理解析和实用代码示例,揭示它们如何共同构建高效的后端系统。构建高性能后端的首选:Nginx反向代理Nginx不仅是一款出色的Web服务器,还是一款强大的反向代理......
  • Nginx与Elasticsearch:高性能后端的完美融合
    在追求卓越后端性能的道路上,Nginx与Elasticsearch是一对黄金组合。本文将从深度原理解析和实际代码示例两个方面,探索这两项技术的协同作用,揭示它们如何共同构建高效的后端系统。打造高性能后端:Nginx反向代理Nginx不仅仅是一款优秀的Web服务器,更是一款强大的反向代理工具。通过将客......
  • 深入探索Elasticsearch的分布式搜索与性能优化
    在后端开发领域,Elasticsearch作为一款强大的分布式搜索与分析引擎,被广泛应用于构建高性能的搜索和数据分析系统。本文将深入探讨Elasticsearch的分布式特性、搜索原理以及性能优化策略。通过结合实际代码示例,为读者提供关于Elasticsearch的深奥知识和实用方法。1.Elasticsearch概......
  • elasticSearch常见的面试题
    常见的面试问题描述使用场景es集群架构3个节点,根据不同的服务创建不同的索引,根据日期和环境,平均每天递增60*2,大约60Gb的数据。调优技巧设计阶段的调优根据业务增长的需求,采取日期模版创建索引,通过rolloverAPI实现滚动索引定义条件,生成新的索引,但都指向一个别名根据别名对索引进行......
  • PATTERN_MATCH环境搭建
    依赖安装首先更新一下软件列表,顺手升级一下软件sudoaptupdatesudoaptupgradeboost库直接使用apt即可安装sudoaptinstalllibboost-all-devLimbo库Limbo库无法用apt安装,并且依赖于其他库,包括flex、bison、zlib。使用apt安装这些依赖库,apt-getinstallflexzlib......
  • 分布式存储系统举例剖析(elasticsearch,kafka,redis-cluster)
    1.概述对于分布式系统,人们首先对现实中的分布式系统进行高层抽象,然后做出各种假设,发展了诸如CAP,FLP等理论,提出了很多一致性模型,Paxos是其中最璀璨的明珠。我们对分布式系统的时序,复制模式,一致性等基础理论特别关注。在共识算法的基础上衍生了选举算法,并且为分布式事务提供......