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单词的文档,那么她可能对包含饺子的文档不感兴趣。 您需要自己决定是只希望对用户感兴趣的匹配项(精确)还是向用户显示尽可能多的可能匹配项(调用)。 这在很大程度上取决于您的应用程序的用例。

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

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

solr 模糊匹配

solr 模糊匹配_Solr中的前缀和后缀匹配相关推荐

  1. Solr中的前缀和后缀匹配

    搜索引擎都是关于查找字符串的. 用户输入一个查询词,然后从反向索引中检索它. 有时,用户正在寻找的值只是索引中值的子字符串,并且用户可能也对这些匹配感兴趣. 对于德语这样的包含复合词(例如Semmel ...

  2. java string 前缀匹配_字符串前缀和后缀匹配

    娜 娜费劲九牛二虎之力终于把糖果吃完了(说好的吃不完呢?骗人,口亨~),于是,缘溪行,忘路之远近.忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤 纷,娜娜甚异之.复前行,欲穷其林.林尽水源,便得一 ...

  3. 视图解析器中配置前缀和后缀---SpringMVC学习笔记(五)

    springmvc.xml中配置的视图解析器中增加jsp路径的前缀和后缀配置: <!-- 配置视图解析器 --><bean class="org.springframewo ...

  4. python正则匹配字符串中的数字_Python正则表达式匹配字符串中的数字

    1.使用"\d+"匹配全数字 代码: import re zen = "Arizona 479, 501, 870. Carlifornia 209, 213, 650. ...

  5. python正则表达式匹配字符串中的电话号码_Python正则表达式匹配字符串中的数字...

    这篇文章主要介绍了Python正则表达式匹配字符串中的数字,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 1.使用"\d+"匹配全数字 代码: ...

  6. python 如何匹配列表中某个单词_Python如何匹配文本文件中多行中的特定单词/数字,并将它们存储在单独的列表中...

    解释您想要的正则表达式及其工作原理 以上所有的答案都有效,但是如果你想真正理解这个问题,我认为这可能是一个很好的方法.首先你要想一想你想找到什么.在 对于前三个,您希望匹配类似name space d ...

  7. python正则表达式匹配网址中的域名_正则表达式匹配域名、网址、url

    DNS规定,域名中的标号都由英文字母和数字组成,每一个标号不超过63个字符,也不区分大小写字母.标号中除连字符(-)外不能使用其他的标点符号.级别最低的域名写在最左边,而级别最高的域名写在最右边.由多 ...

  8. php匹配地址中的省市区,php 正则匹配省市区

    省市区正则匹配 preg_match('/(.*?(省|自治区|北京市|天津市))+(.*?(市|自治州|地区|区划|县))+(.*?(区|县|镇|乡|街道))/', $address, $match ...

  9. KMP算法中的前缀集和后缀集的概念

    举例字符串"ACVSDB" 前缀集为{"A","AC","ACV","ACVS","ACV ...

最新文章

  1. C++ Primer英文版(第5版)
  2. 准备把以前在百毒博客写的一些文章搬运过来
  3. Cadence快捷键设置亲测有效!
  4. 详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。
  5. java 两层while_java – while while循环满足2个条件之一
  6. Django构建简介
  7. OPPO Reno7/Reno7 Pro今天开售:首发IMX709超感光猫眼镜头
  8. springboot细节挖掘(集成ElasticSearch)
  9. 在Thinkphp中使用AJAX实现无刷新分页
  10. 【毕业答辩】毕业设计答辩前期准备
  11. VLOOKUP函数返回错误值#N/A的两种解决方法
  12. 获取rabbitmq连接对象_NET Core使用RabbitMQ
  13. 21世纪高等专业教材21 CENTURY HIGHER PROFESSIONAL TEXTBOOKS RESUME WRITING METHOD PRINCIPLES AND RULES
  14. GNS3 将虚拟机加入组网
  15. 中国计算机学会青年计算机科技论坛
  16. 【HPU】[1732]序列的区间操作
  17. 深入理解计算机网络-4信号编码与调制2
  18. (转)ICO泡沫:8万本金赚套房子和宝马 几分钟十几万没了
  19. linux 操作excel文件,Linux下输出excel文件
  20. Oracle数据库表空间不足 ORA-01653:unable to extend table 表名称 by 8192 in tablespace 表空间名称

热门文章

  1. 【2018.5.12】模拟赛之二-ssl2414 简写单词【字符串】
  2. 【Trie】【费用流】管道监控(loj 3026)
  3. 小麦亩产一千八(jzoj 3461)
  4. 初一模拟赛总结(3.30)
  5. 低价购买(洛谷 1108)
  6. Hadoop生态hive(四)数据类型
  7. JavaFX UI控件教程(二十三)之Menu
  8. Java开发必会的反编译知识
  9. publiccms中,怎么修改默认的端口8080以及默认上下文名称
  10. 计算机入门的一些常用小技巧总结