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,一经查实,立即删除!

相关文章

使用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 …

调试以了解终结器

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

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做…

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

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…

从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;则自动会创建…

Vuex的第一次接触

前言&#xff1a;最近在做Vue实现去哪网&#xff0c;想要实现在城市列表页面&#xff0c;点击某个城市的时候&#xff0c;主页的头部的城市会随着改变&#xff0c;就是首页和城市页面有共用的数据要分享&#xff0c;这里使用Vuex 1. Vuex是什么&#xff1f; 是Vue官方推荐的数…

java IO流小结

Java流操作有关的类或接口&#xff1a; Java流类图结构&#xff1a; 流的概念和作用 流是一组有顺序的&#xff0c;有起点和终点的字节集合&#xff0c;是对数据传输的总称或抽象。即数据在两设备间的传输称为流&#xff0c;流的本质是数据传输&#xff0c;根据数据传输特性将流…

华为android是什么型号,华为手机机型众多,目前这几款最值得入手

华为手机机型众多&#xff0c;目前这几款最值得入手2020-09-22 15:00:033点赞0收藏0评论华为手机可以说是国家手机的代名词。受某种感情的影响&#xff0c;很多人都用华为取代了iPhone。为了表达感情&#xff0c;很多人也纷纷效仿&#xff0c;购买华为手机。但我想说的是支持华…

pt-online-schema-change VS oak-online-alter-table【转】

前言 在上篇文章中提到了MySQL 5.6 Online DDL&#xff0c;如果是MySQL 5.5的版本在DDL方面是要付出代价的&#xff0c;虽然已经有了Fast index Creation&#xff0c;但是在添加字段还是会锁表的&#xff0c;而且在添加删除辅助索引是会加S锁&#xff0c;也就是无法进行写操作。…

vue命令行错误处理

全局安装vue/cli时&#xff1a;npm install -g vue/cli &#xff08;1&#xff09;Error: EACCES: permission denied, access /usr/local/lib/node_modules/vue/cli 原因: 执行命令时没有获得管理员权限 解决办法: 在命令前面加上sudo即可.然后输入电脑的管理员密码操作即可…

RAC(ReactiveCocoa)介绍(一)

最近在学习RAC&#xff0c;之前在iOS工作中&#xff0c;类之间的传值&#xff0c;无非是block、delegate代理、KVO和Notification等这几种方法。在RAC中&#xff0c;同样具备替代block、delegate代理、KVO和Notification&#xff0c;UI target、定时器timer、数据结构等各种方式…

一段简单的html 5 音频,5个用于处理HTML5音频的库和API

在过去的几个月中&#xff0c;我遇到了许多不同的库&#xff0c;它们利用了相对较新的HTML5 Audio API以及更著名的HTML5 Audio Element及其更简单的API。我以为我会在本文中分享这些库中的一小部分&#xff0c;以向您展示如果选择创建需要操纵声音文件的游戏或应用程序&#x…

WinAPI: SetRect 及初始化矩形的几种办法

本例分别用五种办法初始化了同样的一个矩形, 运行效果图:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 class(TForm)Button1: TButton;Button2: TButton;Button3: TButton;Button4: TBu…

备忘录——通过RVA计算文件位置

备忘录——通过RVA计算文件位置 原创&#xff1a;Anders Liu 摘要&#xff1a;本文介绍了如何通过PE文件中某一项的RVA来计算其在文件中的位置。 参考文献 ECMA-335——Common Language Infrastructure (CLI) 4th Edition, June 2006 范畴 该备忘录描述了在分析PE&#xff08;可…

中后端管理系统前后分离、前端框架的实现拙见

一、实现思路 在实践中后台管理系统的前后端分离时&#xff0c;往往会因为业务量的增加使其前端项目难以维护&#xff0c;以及打包时间不理想&#xff0c;还有业务系统与框架之间区分不在明显。本文是本人从另一个角度提出的一种解决方案&#xff0c;希望各位提出宝贵的建议。…