设置Elasticsearch N-Gram Word分析器的过程

说n-gram是一个大话题,这是轻描淡写的。 进行快速搜索,您会发现自己盯着语言学和语言模型,数据挖掘或特定蛋白质的分解对首次亮相文化的衰落所隐含的信息量。

好吧,我在跟那最后一个开玩笑。 但是,如果您是开发人员,希望使用Elasticsearch在应用程序中进行搜索,那么您很有可能需要以实用的方式使用n-gram分析器来进行某些搜索,并且可能需要一些针对性的信息才能获取您的搜索以期望的方式表现。 在Elasticsearch中使用n-gram搜索可以做的事情有很多可能性。 该博客将使您开始思考如何在搜索中使用它们。

一个例子

首先,让我们在这里缩小一下范围。 在很多情况下,使用n-gram可能是指搜索句子,而您的gram则是指句子中的单词。 但是对于今天,我想集中讨论单个单词的细分。 n元语法世界中的单个单词称为带状疱疹。

让我们进一步缩小范围,假设我们想使用此搜索进行近似匹配。 在应用程序中,要搜索单词(名称,用户名)或类似于单词的数据(电话号码),然后以与搜索单词紧密匹配的形式向搜索者提供更多信息,这并不少见。 在这里,我们还希望部分匹配该单词,而不是总是在前面,也不总是在结尾。

为了便于参考,我们假装有一个可以按名称查找动物的站点。 也许这是兽医办公室的前线,而该办公室希望首先以宠物的名字进行所有查找。 当然,您可能会发现自己Swift扩大了搜索范围,以包括其他条件,但举个例子,假设该办公室的所有爱狗人士都疯了,必须使用狗的名字。

分析仪

现在,让我们考虑一下分析仪的需求。 首先,我们已经知道我们想要某种n-gram。 我们想要部分匹配。 其次,上面我们已经决定要搜索单词中的部分匹配项。 在这种情况下,这将仅在一定程度上,正如我们稍后将看到的那样,但是现在我们可以确定我们需要NGram令牌生成器,而不是仅保留从令牌开头开始保留n-gram的Edge NGram令牌生成器。

ElasticSearch Ngrams允许最小和最大克数。 从最小值开始,我们要匹配多少个名字? 好的,默认值为1,但是由于我们已经在处理单个单词的数据,所以如果我们使用一个字母(一个字母组合),我们肯定会得到太多的结果。 实际上,同样的事情也将适用于二元组。 但是,有足够多的人养着三个字母的宠物,我们最好不要走,否则我们可能永远不会在搜索结果中返回名为“ Ace”和“ Rex”的幼犬。 现在我们知道我们的最小克数将是3。 最大克呢? 默认值为2,我们已经超过了最小值。 我们的目标是尽可能多地包含潜在的准确匹配项,但在索引大小存储方面仍然不会发疯。

考虑选择一个过大的数字(如52),并为3个字符到52个字符之间的所有可能可能性分解名称,您会看到随着数据的增长,这很快就会加起来。 这里有些妥协,因为在某些情况下,您最终可能会排除超出最大语法的数据。

有两种方法可以解决此排除问题,一种是包括对字段的第二次映射并使用其他分析器(例如标准分析器),或者使用第二种映射并从精确匹配的速度和准确性中受益字词查询。

在我们的案例中,我们将利用将单独的分析器用于搜索和索引的功能。 我们假设最大值之后的数据与我们的搜索在很大程度上无关,在这种情况下,它极有可能与搜索无关。

因此,这里我们创建索引,然后设置自定义分析器。 关于整体内容,这里的示例将有些简单,但是我希望它们有助于理解。

注意:稍微偏离主题,但是在现实生活中,您将需要以一种更可重用的方式进行操作(例如模板),以便可以轻松使用别名和版本并更新索引,但是为此例如,我只是展示了卷曲索引创建的最简单设置。

这是我们的第一个分析器,创建一个自定义分析器,并使用ngram_tokenizer和我们的设置。 如果您在这里,则可能知道这一点,但是令牌生成器用于将字符串分解为术语或令牌流。 您可以根据需要在此处添加空格和许多其他选项:

curl -XPUT 'localhost:9200/searchpets' -d '{"settings" : {"analysis" : {"analyzer" : {"ngram_analyzer" : {"tokenizer" : "ngram_tokenizer"}},"tokenizer" : {"ngram_tokenizer" : {"type" : "nGram","min_gram" : "3","max_gram" : "8"}}}}}'

我们对此索引创建的响应为{“ acknowledged”:true}。 优秀的。

好了,既然有了索引,使用新的分析仪时数据将是什么样?

curl -XGET'localhost:9200/searchpets/_analyze?analyzer=ngram_analyzer' -d 'Raven'

响应是:

{"tokens":[{"token":"Rav","start_offset":0,"end_offset":3,"type":"word","position":1},{"token":"Rave","start_offset":0,"end_offset":4,"type":"word","position":2},{"token":"Raven","start_offset":0,"end_offset":5,"type":"word","position":3},{"token":"ave","start_offset":1,"end_offset":4,"type":"word","position":4},{"token":"aven","start_offset":1,"end_offset":5,"type":"word","position":5},{"token":"ven","start_offset":2,"end_offset":5,"type":"word","position":6}]}

这是合理的。 所有令牌都在3到5个字符之间生成(显然,因为单词少于8个)。

好的,太好了,现在让我们将其应用于字段。 而且,是的,您绝对可以一步一步完成所有操作,我只是将其分解。

$ curl -XPUT 'http://localhost:9200/searchpets/_mapping/pet' -d '
{"pet": {"properties": {"name": {"type": "string","analyzer": "ngram_analyzer"}}}
}
'

我们在现场测试分析:

curl -XGET 'http://localhost:9200/searchpets/_analyze?field=pet.name' -d 'Raven';

再一次,我们得到了我们期望的结果:

{"tokens":[{"token":"Rav","start_offset":0,"end_offset":3,"type":"word","position":1},{"token":"Rave","start_offset":0,"end_offset":4,"type":"word","position":2},{"token":"Raven","start_offset":0,"end_offset":5,"type":"word","position":3},{"token":"ave","start_offset":1,"end_offset":4,"type":"word","position":4},{"token":"aven","start_offset":1,"end_offset":5,"type":"word","position":5},{"token":"ven","start_offset":2,"end_offset":5,"type":"word","position":6}]}

现在,假设我已经继续并在此处添加了一些记录,并针对以下内容运行简单的匹配查询:{“ query”:{“ match”:{“ name”:“ Pegasus”}}}。

根据我的数据,我们得到以下信息:

"hits": {"total": 2,"max_score": 0.29710895,"hits": [{"_index": "searchpets","_type": "pet","_id": "3","_score": 0.29710895,"_source": {"name": "Pegasus"}},{"_index": "searchpets","_type": "pet","_id": "2","_score": 0.0060450486,"_source": {"name": "Degas"}}]
}
}

我们得到最接近的匹配以及可能实际上是用户正在寻找的关闭选项。

定制分析仪

好的,但是现在我们正在使用一个非常基本的分析器案例。 如果我们需要一个自定义分析器,以便能够处理在搜索和索引上需要不同的分词器的情况,该怎么办? 如果我们想用关键字标记器来限制搜索怎么办?

让我们对其进行更改,以使用针对n元语法的过滤器来设置自定义分析器。 由于我们在下一个搜索中使用了tokenizer关键字和match查询,因此在显示的这些测试用例中,此处的结果实际上与之前的结果相同,但是您会注意到它们的评分方式有所不同。

$ curl -XPUT 'localhost:9200/searchpets' -d '{"settings": {"analysis": {"analyzer": {"namegrams": {"type": "custom","tokenizer": "keyword","filter": ["ngrams_filter"]}},"filter": {"ngrams_filter": {"type": "ngram","min_gram": 3,"max_gram": 8}}}}
}'

现在,我们像以前一样添加一个映射和数据:

curl -XPUT 'http://localhost:9200/searchpets/_mapping/pet' -d '
{"pet": {"properties": {"name": {"type": "string","analyzer": "namegrams"}}}
}
'

我运行另一个匹配查询:{“ query”:{“ match”:{“ name”:“ Pegasus”}}},响应为:

hits": {
"total": 2,
"max_score": 1.1884358,
"hits": [{"_index": "searchpets","_type": "pet","_id": "2","_score": 1.1884358,"_source": {"name": "Pegasus"}},{"_index": "searchpets","_type": "pet","_id": "3","_score": 0.08060065,"_source": {"name": "Degas"}}
]
}

因此,我们进行了设置,并根据关键字标记器和n-grams过滤器获得了期望的结果和评分。 假设我们正在做一些更复杂的查询。 我们可能还添加了其他一些过滤器或标记器。 情况看起来不错,对吗? 好吧,差不多。

我前面提到的所有这些要记住的一个小因素。 我们有一个最大的8克。 那么,当我们拥有一个超过该大小的名称作为搜索条件时,会发生什么呢? 好吧,根据您的搜索,您可能不会获得任何数据。

您可能没有想到这里会发生什么! 您如何避免这种情况? 一种方法是使用不同的index_analyzer和search_analyzer。 拆分这些内容可以使您更好地控制搜索。

因此,假设我们对原始搜索所说的一切都是正确的,那么您的最终设置可能会是这样。 我不会深入探讨查询本身的详细信息,但是我们将假定它将使用指定的search_analyzer(我建议阅读ES文档中有关如何选择分析器进行搜索的层次结构)。

注意:此处search_ngram分析器上的小写标记化器可标准化标记文本,因此所有数字都将被剥离。 此示例适用于此示例,但是使用不同的数据可能会导致意外的结果。

$ curl -XPUT 'localhost/searchpets' -d '{"settings": {"analysis": {"analyzer": {"namegrams": {"type": "custom","tokenizer": "keyword","filter": ["ngrams_filter"]},"search_ngram": {"type": "custom","tokenizer": "lowercase","filter": ["truncate_filter"]}},"filter": {"ngrams_filter": {"type": "ngram","min_gram": 3,"max_gram": 8},"truncate_filter": {"type": "truncate","length": 8}}}}
}
’

然后,最后,我们再次设置映射:

curl -XPUT 'http://localhost:9200/searchpets/_mapping/pet' -d '
{"pet": {"properties": {"name": {"type": "string","index_analyzer": "namegrams","search_analyzer": "search_trigram"}}}
}'

最后的想法

那里有它。 但是,这使得假设超过8个字符的数据不太重要。 如果您要拥有比最大克数更大的数据,并且类似数据,您可能会发现自己需要进一步调整。

在Elastisearch中使用n-gram搜索可以做的事情有很多可能性。 我希望这可以让您开始思考如何在搜索中使用它们。

翻译自: https://www.javacodegeeks.com/2015/11/anatomy-of-setting-up-an-elasticsearch-n-gram-word-analyzer.html

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

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

相关文章

linux windows 丢失,Win10预览版9879硬盘丢失的Linux解决方案

IT之家讯 12月3日消息,最近IT之家论坛网友九仙仙总结了Win10预览版9879硬盘问题的解决方法,并在论坛中发布出来。经测试,此为快速有效的解决方法,故公之于众供朋友们参考。以下为作者原文。开头说明两点:1、这是我个人…

linux单网卡多拨Adsl,ROS单线多拨pppoe

#设置内网IP地址/ ip add add interfaceether1address192.168.0.254/255.255.255.0#设置共享上网/ ip firewall nat add actionmasquerade chainsrcnatsrc-address192.168.0.0/255.255.255.0#设置ADSL拔号/ interface pppoe-client add name"pppoe-out1" interfaceet…

Android开发——Android系统启动以及APK安装、启动过程

0. 前言 从Android手机打开开关,到我们可以使用其中的app时,这个启动过程到底是怎么样的?1. 系统上电当给Android系统上电,在电源接通的瞬间,CPU内的寄存器和各引脚均会被置为初始状态,CPU复位之后&#…

linux生成文件清单,Linux 获取文件名称生成列表 txt - create_filelist

Linux 获取文件名称生成列表 txt - create_filelist1. find/home/strong/MOTChallenge/MOT16/MOT16/train/MOT16-04/img1/ 文件夹下所有 *.jpg (000001.jpg - 001050.jpg) 的路径 图片名信息写入 txt 文件。1.1 llstrongforeverstrong:~/MOTChallenge/MOT16/MOT16/train/MOT16…

jvm线程分析命令_JVM:如何分析线程转储

jvm线程分析命令本文将教您如何分析JVM线程转储,并查明问题的根本原因。 以我的观点,线程转储分析是掌握Java EE生产支持的任何个人最重要的技能。 您可以从线程转储快照中获取的信息量通常远远超出您的想象。 我的目标是与您分享我在过去10年中积累的有…

[na]华为acl(traffic-filter)和dhcp管理

这个是财务网络的一个问题, 要求财务的某台机器能访问其他部门区的打印机. 其他部门是不能访问到财务网络的. 华为alc配置实例:-traffic-filter # 在VLAN100上配置基于ACL的报文过滤&#xff0c;允许源IP地址为192.168.0.2/32的报文通过&#xff0c;丢弃其他报文。 <HUAWEI&…

svn 1.6 linux 下载,LINUX下Subversion1.6.17 部署

1、服务器版本和安装软件服务器版本&#xff1a;Redhat Enterprise 5.5 32bit安装软件&#xff1a;apr-1.3.12.tar.gzapr-util-1.3.12.tar.gzhttpd-2.2.9.tar.gzsqlite-amalgamation-3.7.3.tarsubversion-1.6.17.tar.bz2subversion-deps-1.6.17.tar.bz22、安装检查操作系统http…

JBoss Fuse –使用MVEL将您的静态配置转换为动态模板

最近&#xff0c;我重新发现了我遗忘的JBoss Fuse功能&#xff0c;并且我认为其他人可能会从此提醒中受益 。 这篇文章将重点放在JBoss Fuse和Fabric8上&#xff0c;但所有正在寻找最小侵入性方法来为其静态配置文件添加一定程度的动态支持的开发人员也可能会对此感兴趣。 在…

在linux中dns不安装coching,ubuntu 8.04下openldap的安装和使用

ubuntu 8.04上openldap的安装和使用1、安装openldap。$ sudo apt-get install slapd ldap-utils2、配置openldap。$ sudo /etc/ldap/slapd.conf需要修改的有以下4处。# The base of your directory in database #1# 域名前缀suffix "dcpeercoaching,dccn"# …

linux 拿shell,linux下备份拿shell[渗透必备]

关于php包含Apache日志的利用,其实也就是利用提交的网址里有php语句&#xff0c;然后再被Apache服务器的日志记录&#xff0c;然后php再去包含执行&#xff0c;从而包含了去执行。当然&#xff0c;这种办法最大的弊端是Apache日志肯定会过大&#xff0c;回应的时候当然会超时什…

信息系统开发内容

1.按照用于质量管理的能力成熟度模型&#xff08;CMM&#xff09;描述系统开发过程的动机。 2.区分系统生命周期和系统开发方法 3.描述系统开发的10个基本原理 4.定义问题、机会和指示——系统开发项目的能力 5.描述用于把问题、机会和指示进行分类的PIECES框架 6.描述系统开发…

jee neow_JEE7:展望新时代

jee neow计划于2012年下半年发布的Java EE 7预计的JSR都已启动并正在运行。 Java EE 7发行版是日期驱动的&#xff0c;它将反映该行业迁移到云中时不断变化的需求&#xff1a;任何未准备就绪的内容将推迟到Java EE 8中使用 。 这是Java EE 7平台中不同规范的关键功能的更新和摘…

Linux怎么更改声音板卡顺序,51CTO博客-专业IT技术博客创作平台-技术成就梦想

SUN M8000主机 IOU板卡硬件更换一、故障现象1.日志分析XSCF> showstatus*IOU#0 Status:Degraded;XSCF> showlogs -v errorDate: May 24 20:44:22 CST 2019 Code: 80002000-33010000-0167058a00000000Status: Alarm Occurred: May 24 20:44:20.367 C…

Class.getResource和ClassLoader.getResource的区别分析

原文&#xff1a;http://swiftlet.net/archives/868 在Java中获取资源的时候&#xff0c;经常用到Class.getResource和ClassLoader.getResource&#xff0c;本文给大家说一下这两者方法在获取资源文件的路径差异。Class.getResource(String path)path不以/开头时&#xff0c;默…

设计模式的Java 8 Lambda表达式–命令设计模式

在本博客中&#xff0c;我将说明如何使用Java 8 Lambda表达式以函数式编程方式实现命令模式 。 命令模式的目的是将请求封装为对象&#xff0c;从而为具有不同请求&#xff0c;队列或日志请求的客户端参数化&#xff0c;并支持相应的操作。 命令模式是一种编写通用代码的方法&a…

凝思linux系统显卡设置,TaiShan服务器安装凝思操作系统Linx6.0.90并设置独立显卡WX2100输出...

TaiShan服务器安装凝思操作系统Linx6.0.90并设置独立显卡WX2100输出环境准备&#xff1a;TaiShan 2280服务器&#xff0c;凝思操作系统Linx6.0.90 arm64&#xff0c;WX2100显卡&#xff0c;WX2100显卡固件和驱动安装包第1步&#xff0c;上电服务器&#xff0c;登录BMC输入用户名…

JMeter3.0_插件管理

JMeter Plugins 一直以来&#xff0c;JMeter Plugins为我们提供了很多高价值的JMeter插件&#xff0c;比如: 用于服务器性能监视的PerfMon Metrics Collector用于建立压力变化模型的Stepping Thread Group用于Json解析的JSON Path Extractor用于展示响应时间曲线的Response Tim…

linux update语句,关于Update语句的调整(5-1)

调整方法二&#xff1a;建立临时表&#xff0b;Merge(&#xff11;)1.调整方法二&#xff1a;建立临时表&#xff0b;Merge通过建立临时表保存中间结果并结合merge语句的方法对语句进行调整。背景知识简介l临时表简介数据库中的所有会话均可以访问临时表&#xff0c;但只有插入…

JavaWeb总结(四)

使用Servlet发送服务器端响应信息 Servlet API中定义一个专门的接口类javax.servlet.http.HttpServletResponse用于创建HTTP响应&#xff0c;包括HTTP协议的状态行、响应头以及消息体&#xff1b; HTTP响应示例 设置响应状态行 - 状态行分为HTTP协议、状态码和状态描述三个部分…

java ee开发环境_设置Java EE 6开发环境

java ee开发环境本教程简要说明了如何设置典型的环境来开发基于Java EE 6的应用程序。 除了可以正常工作的Windows XP客户端具有足够的CPU能力和内存外&#xff0c;本教程没有其他先决条件。 在教程中&#xff0c;我们将需要安装以下组件&#xff1a; Java 6 JDK更新26 适用于…