郑州市做网站的公司,陕西工程项目信息网,搞定设计在线制作,财务公司经营范围solr 模糊匹配搜索引擎都是关于查找字符串的。 用户输入一个查询词#xff0c;然后从反向索引中检索它。 有时#xff0c;用户正在寻找的值只是索引中值的子字符串#xff0c;并且用户可能也对这些匹配感兴趣。 对于德语这样的包含复合词#xff08;如Semmelkndel#xff… solr 模糊匹配 搜索引擎都是关于查找字符串的。 用户输入一个查询词然后从反向索引中检索它。 有时用户正在寻找的值只是索引中值的子字符串并且用户可能也对这些匹配感兴趣。 对于德语这样的包含复合词如Semmelknödel的语言这尤其重要其中Knödel表示饺子而Semmel专门针对这种词。 通配符 为了演示方法我使用了非常简单的模式。 文档由一个文本字段和一个ID组成。 Github上也可以进行配置和单元测试。 fieldsfield nameid typestring indexedtrue storedtrue requiredtrue multiValuedfalse /field nametext typetext_general indexedtrue storedfalse/
/fields
uniqueKeyid/uniqueKey
typesfieldType namestring classsolr.StrField sortMissingLasttrue /fieldType nametext_general classsolr.TextField positionIncrementGap100analyzertokenizer classsolr.StandardTokenizerFactory/filter classsolr.LowerCaseFilterFactory//analyzer/fieldType
/types 在进行前缀或后缀匹配时非常流行的一种方法是在查询时使用通配符。 这可以通过编程方式完成但是您需要注意然后正确转义任何用户输入。 假设您在索引中包含术语饺子 并且用户输入了术语dump 。 如果要确保查询词与索引中的文档匹配您可以在应用程序代码中向用户查询添加通配符以便将生成的查询转储为* 。 通常在执行此类过多操作时应格外小心如果用户实际上正在寻找包含dump单词的文档那么她可能对包含饺子的文档不感兴趣。 您需要自己决定是只希望对用户感兴趣的匹配项精确还是向用户显示尽可能多的可能匹配项调用。 这在很大程度上取决于您的应用程序的用例。 您可以通过提高与您的学期的完全匹配来增加用户体验。 您需要创建一个更复杂的查询但是这样包含完全匹配项的文档将获得更高的分数 dump^2 OR dump* 在创建这样的查询时您还应注意用户不能添加会使查询无效的字词。 escapeQueryChars类的SolrJ方法escapeQueryChars可用于转义用户输入。 如果现在考虑后缀匹配则查询可能会变得相当复杂并且在客户端创建这样的查询并不适合每个人。 根据您的应用程序另一种方法可能是更好的解决方案您可以在索引期间创建另一个包含NGram的字段。 前缀与NGrams匹配 NGrams是索引术语的子字符串您可以将其放在其他字段中。 这些子字符串可用于查找因此不需要任何通配符。 使用edismax处理程序您可以在字段上自动设置用于完全匹配的提升从而获得与上述相同的行为。 对于前缀匹配我们可以使用为其他字段配置的EdgeNGramFilter ...field nametext_prefix typetext_prefix indexedtrue storedfalse/
...copyField sourcetext desttext_prefix/
... fieldType nametext_prefix classsolr.TextField positionIncrementGap100analyzer typeindextokenizer classsolr.LowerCaseTokenizerFactory/filter classsolr.EdgeNGramFilterFactory minGramSize3 maxGramSize15 sidefront//analyzeranalyzer typequerytokenizer classsolr.LowerCaseTokenizerFactory//analyzer/fieldType 在索引期间文本字段值将复制到text_prefix字段并使用EdgeNGramFilter进行分析。 从字符串的开头开始将为3到15之间的任何长度创建克。 当为术语饺子建立索引时它将是 哑巴 倾倒 垃圾堆 杜普利 杜普林 饺子 在查询期间该词不会再次拆分因此可以使用与子字符串完全匹配的词。 与往常一样Solr管理员后端的分析视图对于查看实际的分析过程可能会很有帮助。 现在您可以使用dismax处理程序按原样传递用户查询并通过添加参数qftext^2,text_prefix来建议它在您的字段中进行搜索。 后缀匹配 对于具有复合词的语言通常也需要进行后缀匹配。 如果用户查询术语Knödel 水饺则包含术语Semmelknödel的文档也应匹配。 使用Solr版本高达4.3这没问题。 您可以使用EdgeNGramFilterFactory从字符串的后面开始创建克。 ...field nametext_suffix typetext_suffix indexedtrue storedfalse/
... copyField sourcetext desttext_suffix/
...fieldType nametext_suffix classsolr.TextField positionIncrementGap100analyzer typeindextokenizer classsolr.StandardTokenizerFactory/filter classsolr.LowerCaseFilterFactory/filter classsolr.EdgeNGramFilterFactory minGramSize3 maxGramSize15 sideback//analyzeranalyzer typequerytokenizer classsolr.KeywordTokenizerFactory/filter classsolr.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 nametext_suffix classsolr.TextField positionIncrementGap100analyzer typeindextokenizer classsolr.LowerCaseTokenizerFactory/filter classsolr.ReverseStringFilterFactory/filter classsolr.EdgeNGramFilterFactory minGramSize3 maxGramSize15 sidefront/filter classsolr.ReverseStringFilterFactory//analyzeranalyzer typequerytokenizer classsolr.LowerCaseTokenizerFactory//analyzer
/fieldType 现在这将产生与以前相同的结果。 结论 是否要通过添加通配符来处理查询或者是否应该使用NGram方法在很大程度上取决于您的用例也取决于您的口味。 我个人大部分时间都在使用NGrams因为磁盘空间通常与我正在从事的项目无关。 Lucene 4中的通配符搜索变得更快了所以我怀疑那里是否还有真正的好处。 不过我倾向于在索引期间进行尽可能多的处理。 翻译自: https://www.javacodegeeks.com/2014/05/prefix-and-suffix-matches-in-solr.htmlsolr 模糊匹配