Elasticsearch之match_phrase小坑记录
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":
}
}
}
}
}
}
}
这里,为了验证分词,同时使用了ik_smart和ik_max两种分词。
实际开发中不需要,因为:两种分词共存,会导致导入数据创建索引的时候,索引会非常大,对磁盘和检索性能都会有影响。
步骤2:插入文档
POST ik_index/ik_type/
{
"title":"公路局正在治理解放大道路面积水问题"
}
步骤3:实施检索
POST ik_index/ik_type/_search
{
"profile":"true",
"query":
{
"match_phrase":
{
"title.ik_my_max":"道路"
}
}
}
搜索结果如下:
无结果返回。
{
"took": ,
"timed_out": false,
"_shards": {
"total": ,
"successful": ,
"failed":
},
"hits": {
"total": ,
"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": ,
"end_offset": ,
"type": "CN_WORD",
"position":
}
而检索的时候,而道路拆分为: 道路0 道1 路2
match_phrase检索时候,文档必须同时满足以下两个条件,才能被检索到:
1)分词后所有词项都出现在该字段中;
2)字段中的词项顺序要一致。
位置信息可以被存储在倒排索引中,因此 match_phrase 查询这类对词语位置敏感的查询, 就可以利用位置信息去匹配包含所有查询词项,且各词项顺序也与我们搜索指定一致的文档,中间不夹杂其他词项。
为了验证如上的解释,新增一篇“道路”相关的title,检验一下:
POST ik_index/ik_type/
{
"title":"党员干部坚持走马克思主义道路的重要性"
}
注意:这时,搜索道路是可以匹配到的。
"hits": {
"total": ,
"max_score": 1.9684901,
"hits": [
{
"_index": "ik_index",
"_type": "ik_type",
"_id": "",
"_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":
}
}
}
}
经验证: 关键词”理解”、”解放”、”道路”、“理解放大”,都能搜出这篇文档。
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。
Elasticsearch之match_phrase小坑记录的更多相关文章
- jquery事件委托遇到的小坑记录
<script type="text/javascript" src="../../lib/jquery-1.11.2.min.js"></s ...
- CentOS安装时小坑记录
在安装CentOS的时候,由于第一次安装小白,将VM虚拟机的内存设置为512M,导致进行安装的时候无法进入正常的画面安装模式,只能使用简版安装界面,可能对于很多小白不是很熟悉,特此记录,安装CentO ...
- ionic3.x开发小坑记录(一)
自定义font的时候,在assets中创建的文件夹名字别用fonts,会与ionic默认样式冲突,在浏览器中调试是正常的,到手机上就出问题了. 在html中写img的src直接如图 assets前面 ...
- 折腾mysql的小坑记录
1.安装 CentOS下先卸载自带的mariadb rpm -qa | grep mariadb mariadb-libs--.el7_2.x86_64 mariadb--.el7_2.x86_64 ...
- php 小坑记录
1 empty PHP<=5.5不能用于判断一个表达式的执行结果并且netbeans 和eclipse编辑器识别不出来此错误 含有此用法的 类 和页面将会报错 empty($this-> ...
- 微信小程序开发技巧及填坑记录
以下是自己在开发过程中遇到的坑和小技巧,记录以下: 1.出现了 page[pages/XXX/XXX] not found.May be caused by :1. Forgot to add pag ...
- iOS工作小技巧及填坑记录
以下是本人在iOS开发工作中使用的一些小技巧,记录一下. 1.使用XXX.pch文件便捷开发+加速Build 在IOS开发的项目中有一个XX_Prefix.pch XX_Prefix.pch:扩展名. ...
- 微信小程序发送红包功能。填坑记录
微信官方文档 1.开通条件 (1)商户号已入驻90日 (2)商户号有连续30天正常交易 (3)只有企业资质的商户才有资格申请 2.注意事项 (1)目前小程序红包仅支持用户微信扫码打开小程序 (2)小程 ...
- elasticsearch 单节点搭建与爬坑记录
elasticsearch 单节点搭建与爬坑记录 prepare 虚拟机或者云服务器(这里用的是阿里云ECS) linux---centos7 安装完毕的jdk 相应的安装包(在https:/ ...
随机推荐
- webstorm vscode 常用设置
webstorm常用的设置及操作图解 VS Code 新建vue文件初始化模板 VSCode新建vue文件自定义模板
- GOLANG 1.9 语言规范
GOLANG 1.9 语言规范 - CSDN博客 https://blog.csdn.net/libing_thinking/article/details/77671607
- 【题解】P3939数颜色
[题解]P3939 数颜色 不要数据结构和模板学傻了... 考虑到兔子们交换都是相邻的,说明任何一次交换只会引起\(O(1)\)的变化. 我们开很多\(vector\)存没种兔子的下标就好了.到时候二 ...
- python+NLTK 自然语言学习处理三:如何在nltk/matplotlib中的图片中显示中文
我们首先来加载我们自己的文本文件,并统计出排名前20的字符频率 if __name__=="__main__": corpus_root='/home/zhf/word' word ...
- python cookbook第三版学习笔记十四:类和对象(五)代理类以及内存回收
代理类: 代理类的作用其实有继承有些类似,如果你想将某个实例的属性访问代理到内部另外一个实例中去,可以用继承也可以用代理.来看下代理的应用: class A: def spam(self,x) ...
- wifi debug command
==================================================================================================== ...
- 【ELK】Elasticsearch的备份和恢复
非原创,只是留作自己查询使用,转自http://keenwon.com/1393.html Elasticsearch的备份和恢复 备份 Elasticsearch的一大特点就是使用简单,api也比较 ...
- 友盟分享到微信的几点备忘(IOS)
1.下载最新的友盟分享版本,参考友盟官方的demo 2.注册微信开放平台用户,不是公众平台,注册应用 3.参考文档和demo,加入sdk包和相应的lib 4.在plist加入URL types.URL ...
- 私有 npm 仓库的搭建
cnpm 是企业内部搭建 npm 镜像和私有 npm 仓库的开源方案,当企业业务逻辑相关的模块可能不适合开源.这部分私有的模块就可以放在私有 npm 仓库中来管理和维护. 以下为搭建私有 npm 的详 ...
- 加州小学grade1,学习计划
Visual vocabulary Grammar Spelling Maths Chapter 1 Patterns and Number SenseChapter 2Understanding A ...