Solr中的前缀和后缀匹配

搜索引擎都是关于查找字符串的。 用户输入一个查询词,然后从反向索引中检索它。 有时,用户正在寻找的值只是索引中值的子字符串,并且用户可能也对这些匹配感兴趣。 对于德语这样的包含复合词(例如Semmelknödel)的语言,这尤其重要,其中Knödel表示饺子,而Semmel专门介绍这种词。

通配符

为了演示方法,我使用了非常简单的模式。 文档由一个文本字段和一个ID组成。 在Github上也可以进行配置和单元测试。

<fields><field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /><field name="text" type="text_general" indexed="true" stored="false"/>
</fields>
<uniqueKey>id</uniqueKey>
<types><fieldType name="string" class="solr.StrField" sortMissingLast="true" /><fieldType name="text_general" class="solr.TextField" positionIncrementGap="100"><analyzer><tokenizer class="solr.StandardTokenizerFactory"/><filter class="solr.LowerCaseFilterFactory"/></analyzer></fieldType>
</types>

在进行前缀或后缀匹配时非常流行的一种方法是在查询时使用通配符。 这可以通过编程方式完成,但是您需要注意,然后正确转义任何用户输入。 假设您在索引中包含术语饺子 ,并且用户输入了术语dump 。 如果要确保查询词与索引中的文档匹配,您可以在应用程序代码中向用户查询添加通配符,以便将生成的查询转储为*

通常,在进行此类过多操作时,您应格外小心:如果用户实际上正在查找包含dump单词的文档,那么她可能对包含dumpling的文档不感兴趣。 您需要自己决定是只希望对用户感兴趣的匹配项(精确)还是向用户显示尽可能多的可能匹配项(调用)。 这在很大程度上取决于您的应用程序的用例。

您可以通过提高与您的学期的完全匹配来增加用户体验。 您需要创建一个更复杂的查询,但是这样,包含完全匹配项的文档将获得更高的分数:

dump^2 OR dump*

在创建这样的查询时,您还应注意用户不能添加会使查询无效的字词。 escapeQueryChars类的SolrJ方法escapeQueryChars可用于转义用户输入。

如果现在考虑后缀匹配,则查询可能会变得非常复杂,并且在客户端创建这样的查询并不适合每个人。 根据您的应用程序,另一种方法可能是更好的解决方案:您可以在索引期间创建另一个包含NGram的字段。

前缀与NGrams匹配

NGrams是索引术语的子字符串,您可以将其放在其他字段中。 这些子字符串可用于查找,因此不需要任何通配符。 使用(e)dismax处理程序,您可以在字段上自动设置用于完全匹配的提升,从而获得与上述相同的行为。

对于前缀匹配,我们可以使用为其他字段配置的EdgeNGramFilter :

...<field name="text_prefix" type="text_prefix" indexed="true" stored="false"/>
...<copyField source="text" dest="text_prefix"/>
...    <fieldType name="text_prefix" class="solr.TextField" positionIncrementGap="100"><analyzer type="index"><tokenizer class="solr.LowerCaseTokenizerFactory"/><filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="15" side="front"/></analyzer><analyzer type="query"><tokenizer class="solr.LowerCaseTokenizerFactory"/></analyzer></fieldType>

在索引期间,文本字段值将复制到text_prefix字段,并使用EdgeNGramFilter进行分析。 从字符串的开头开始,将创建3到15之间任何长度的克。 当为术语饺子建立索引时,它将是:

  • 哑巴
  • 倾倒
  • 垃圾堆
  • 杜普利
  • 杜普林
  • 饺子

在查询期间,该词不会再次拆分,因此可以使用与子字符串完全匹配的词。 像往常一样,Solr管理员后端的分析视图可以帮助您查看实际的分析过程。

分析

使用dismax处理程序,您现在可以按原样传递用户查询,并通过添加参数qf=text^2,text_prefix来建议它在您的字段中进行搜索。

后缀匹配

对于具有复合词的语言,通常也需要进行后缀匹配。 如果用户查询术语Knödel (水饺),则包含术语Semmelknödel的文档也应匹配。

使用Solr版本高达4.3,这没有问题。 您可以使用EdgeNGramFilterFactory从字符串的后面开始创建克。

...<field name="text_suffix" type="text_suffix" indexed="true" stored="false"/>
...    <copyField source="text" dest="text_suffix"/>
...<fieldType name="text_suffix" class="solr.TextField" positionIncrementGap="100"><analyzer type="index"><tokenizer class="solr.StandardTokenizerFactory"/><filter class="solr.LowerCaseFilterFactory"/><filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="15" side="back"/></analyzer><analyzer type="query"><tokenizer class="solr.KeywordTokenizerFactory"/><filter class="solr.LowerCaseFilterFactory"/></analyzer></fieldType>
...

这将创建索引术语的后缀,其中也包含术语knödel,因此我们的查询有效。

但是,使用较新版本的Solr时,在建立索引期间会遇到问题:

java.lang.IllegalArgumentException: Side.BACK is not supported anymore as of Lucene 4.4, use ReverseStringFilter up-front and afterwardat org.apache.lucene.analysis.ngram.EdgeNGramTokenFilter.(EdgeNGramTokenFilter.java:114)at org.apache.lucene.analysis.ngram.EdgeNGramTokenFilter.(EdgeNGramTokenFilter.java:149)at org.apache.lucene.analysis.ngram.EdgeNGramFilterFactory.create(EdgeNGramFilterFactory.java:52)at org.apache.lucene.analysis.ngram.EdgeNGramFilterFactory.create(EdgeNGramFilterFactory.java:34)

您不能再将EdgeNGramFilterFactory用于后缀ngram。 但是幸运的是,堆栈跟踪还建议我们如何解决该问题。 我们必须将其与ReverseStringFilter结合使用:

<fieldType name="text_suffix" class="solr.TextField" positionIncrementGap="100"><analyzer type="index"><tokenizer class="solr.LowerCaseTokenizerFactory"/><filter class="solr.ReverseStringFilterFactory"/><filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="15" side="front"/><filter class="solr.ReverseStringFilterFactory"/></analyzer><analyzer type="query"><tokenizer class="solr.LowerCaseTokenizerFactory"/></analyzer>
</fieldType>

现在将产生与以前相同的结果。

结论

是否要通过添加通配符来处理查询,或者是否应该使用NGram方法,在很大程度上取决于您的用例,也取决于您的口味。 我个人大部分时间都在使用NGrams,因为磁盘空间通常与我正在从事的项目无关。 在Lucene 4中,通配符搜索变得更快了,所以我怀疑那里是否还有真正的好处。 不过,我倾向于在索引期间进行尽可能多的处理。

翻译自: https://www.javacodegeeks.com/2014/05/prefix-and-suffix-matches-in-solr.html

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

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

相关文章

评价viper4android,ViPer4android. FX顶级音效!

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼名称&#xff1a;OPPO X903 杜比音效脉冲反馈样本 For VIPER4Android FX v2.0样本数量&#xff1a;72适配V4A版本&#xff1a;ViPER4Android FX v2.2.0.1 或更高适用范围&#xff1a;耳机内放制作者&#xff1a;漫游因特网授权&…

使用FormData进行Ajax请求上传文件

Servlet3.0开始提供了一系列的注解来配置Servlet、Filter、Listener等等。这种方式可以极大的简化在开发中大量的xml的配置。从这个版本开始&#xff0c;web.xml可以不再需要&#xff0c;使用相关的注解同样可以完成相应的配置。 我笔记里也有记文件上传&#xff1a;https://w…

基于 jq 实现拖拽上传 APK 文件,js解析 APK 信息

技术栈 jquery文件上传&#xff1a;jquery.fileupload&#xff0c;github 文档apk 文件解析&#xff1a;app-info-parser&#xff0c;github 文档参考&#xff1a;前端解析ipa、apk安装包信息 —— app-info-parser 支持功能 点击或拖拽上传 apk 文件校验文件类型及文件大小js …

POI获取WORD信息

最近由于工作需要&#xff0c;调研了一下关于poi获取word字体信息方面的方法&#xff0c;在这里mark一下。 首先word格式分为doc和docx&#xff0c;分别利用HWPFDocument和XWPFDocument对文档进行解析&#xff0c;话不多说&#xff0c;直接贴代码&#xff1a; 解析doc格式1 imp…

安全性

•完全适用ASP.NET的认证机制 –可以使用FormsAuthentication •WebService方法可以操作Cookie –Impersonation –PrincipalPermissionaspx<form id"form1"runat"server"><asp:ScriptManager runat"server"ID"ScriptManager1&quo…

调试以了解终结器

这篇文章涵盖了Java内置概念之一&#xff0c;称为Finalizer 。 这个概念实际上是众所周知的&#xff0c;也是众所周知的&#xff0c;这取决于您是否有足够的时间来仔细研究一下java.lang.Object类。 就在java.lang.Object本身中&#xff0c;有一个名为finalize&#xff08;&…

C++ constexpr变量和constexpr函数

constexpr 类型变量必须用常量表达式或 constexpr 函数来初始化&#xff1a; constexpr int a10;   constexpr int ba10;   constexpr int cd();  //当 d()为一个 constexpr 函数时才可以 constexpr 函数的形参和返回值都只能是字面型类型&#xff0c;且只能有一条 retur…

Zookeeper实现注册与发现

1.Zookeeper的数据模型 (1) Zookeeper的数据模型&#xff0c;类似于树形结构&#xff1a; (2) Zookeeper的每一个节点成为称为Znode&#xff0c;主要用来存储数据。 data : 存储数据信息。acl : 记录Znode的访问权限。child : 当前节点的子节点引用。stat &#xff1a;包含Zn…

class 命名规范

本文是从简书复制的, markdown语法可能有些出入, 想看"正版"和更多内容请关注 简书: 小贤笔记 注: 文章摘自 penggelies07- 简书, super晴天 - CSDN 常见class关键词 布局类&#xff1a;header, footer, container, main, content, aside, page, section 包裹类&am…

web策略类游戏开发(四)一个可以承载万人在线的架构

web策略类游戏开发(四)一个可以承载万人在线的架构 Webgame现在已经开始需要进入大统一服务器时代&#xff0c;每个游戏区域容纳的玩家数量将从现在的几万人发展到几十万人&#xff0c;因此在新的背景下&#xff0c;webgame如何处理大量用户的请求将成为问题。目前一台asp.net做…

htc g7 android 4.4,HTC G7刷机,从WM手机刷到了安卓,开启了新的刷机体验....

2011.0914.晚上22&#xff1a;00使用2010的教程刷机&#xff0c;降级时黑屏。使用老的教程&#xff0c;一开始降级从094降到0.83(2010技术)黑屏&#xff0c;但是未板砖&#xff0c;还有开机声音&#xff0c;无法控制机器。没办法&#xff0c;只能使用RUU技术&#xff0c;window…

Java的编年史和低延迟

总览 我正在看Typesafe的Rolan Kuhn在介绍反应流方面的出色演讲&#xff0c;乍一看似乎与《纪事报》有一些相似的目标&#xff0c;但是当您深入研究细节时&#xff0c;对我来说显然有一些关键假设是根本不同。 关键假设 《纪事》设计的主要假设是 低延迟是您的问题&#xff0c…

复制物料时不复制安全库存

1.打开bos&#xff0c;选择物料-功能控制 2.把允许复制去掉 转载于:https://www.cnblogs.com/RogerLu/p/10441588.html

CSS实现水平垂直居中

1、需求分析 子元素在父元素中水平垂直居中 2、技术分析 基础的css、html 3、详细分析 如图: 3.1 HTML部分 如图所示&#xff0c;大边框内包含一个小边框两部分&#xff0c;设置一个父元素div和一个子元素div。 <div class"container">父元素<div class…

2008/5/5

go haywire 非常生气Imagination is the source of creation. 想象是创造之源.转载于:https://www.cnblogs.com/fishert/archive/2008/05/06/1184243.html

鸿蒙3部曲先看哪部,讨论雪鹰与鸿蒙三部曲的关系

1、相信番茄的每部小说出来&#xff0c;心里都在想这会不会是鸿蒙三部曲的最后一部呢&#xff0c;鸿蒙金榜最后一位掌控者呢。2、但是隔了这么多部&#xff0c;番茄依旧未写&#xff0c;第三部&#xff0c;让人不禁思考&#xff0c;会不会第三部是番茄的封山之作呢。3、如果说前…

python装饰器概念与应用

格式一&#xff1a;装饰器外层不传参&#xff0c;内层传参 user_status False # 用户登录了就把这个改成Truedef login(func): # 把要执行的henan模块从这里传进来def inner(*args, **kwargs): # 再定义一层函数&#xff0c;参数为henan的参数_username "alex" …

从Java连接到Cassandra

在我的帖子Hello Cassandra中 &#xff0c;我研究了如何下载Cassandra NoSQL数据库并使用cqlsh连接到Cassandra数据库。 在本文中&#xff0c;我将介绍从Java客户端连接到Cassandra数据库的基础知识。 尽管有几种可用于从Java访问Cassandra数据库的 框架 &#xff0c;但我将在…

Django---Model操作

一、字段 1 AutoField(Field)2 - int自增列&#xff0c;必须填入参数 primary_keyTrue3 4 BigAutoField(AutoField)5 - bigint自增列&#xff0c;必须填入参数 primary_keyTrue6 7 注&#xff1a;当model中如果没有自增列&#xff0c;则自动会创建…

8. Action过滤

Action过滤原文: http://quickstarts.asp.net/3-5-extensions/mvc/ActionFiltering.aspx1. 介绍一般Action与用户动作是一对一的关系,用户的某一个动作对应一个特定的Action.然而,有时你可能会希望在Action执行的前后执行指定的操作,MVC中可以通过Action过滤器来实现这个功能.A…