search - 如何使 SOLR 查询语法中的字符可搜索?

标签 search solr lucene

我有这个问题,我已经尝试解决很长一段时间了。我不是solr专家,我还在学习它。

我的系统中有一种特殊类型的 ID,用户必须可以搜索它。问题是,这些 ID 包含一些 solr 特殊字符。顺便说一下,这些 ID 与其他搜索词一起存储在 terms_txt 字段中。

一些 ID 示例:292/20171.2.61-962-37/2017
我将第一个称为“简单的”,第二个称为“复杂的”。

根据我在互联网上的报道,如果我们进行短语搜索,这种搜索应该是可能的。因此,如果我们在 ID 周围添加撇号,它应该可以工作。但不幸的是事实并非如此。我将在这里发布我的 solr 4.0 模式和我的查询示例,希望您能发现它的问题所在。如果短语搜索是我问题的答案,那么一定是 solr 模式或我的查询(代码)出了问题。

在我的示例中,我正在搜索“292/2017”作为短语。我的索引中只有一个条目包含此短语,因为这种字符组合是唯一的(它是某种 ID,但我们将其与所有其他术语一起插入到 terms_txt 字段中)

这是通过 solr admin 执行的查询,它找到了很多结果,但应该只有 1 个。看起来 solr 将 '/' 字符处理为空格,并忽略短于 3 个字母的术语(忽略少于 3 个字母的术语)是我们想要的,但不是短语搜索):

INFO: [collection1] webapp=/solr-example path=/select params={q=terms_txt:"44/2017"&wt=xml} hits=31343 status=0 QTime=6 

所以基本上,在这个例子中,solr 找到了所有带有 2017 术语的记录,这很糟糕......

这是使用应用程序逻辑执行的查询。它更复杂,但问题是相同的:

INFO: [collection1] webapp=/solr-example path=/select params={mm=100%25&json.nl=flat&fl=id&start=0&sort=date_in_i+desc&fq=type_s:2&fq=date_in_i:[20161201+TO+*]&fq=date_in_i:[*+TO+20171011]&fq=subtype_s:(2+4+6+8)&fq=terms_txt:"\"10/2017\""&fq=language_is:0&rows=10&bq=&q=\"10\/2017\"&tie=0.1&defType=edismax&omitHeader=true&qf=terms_txt&wt=json} hits=978 status=0 QTime=2

这就是 terms_txt 条目在索引中的样子:

<arr name="terms_txt">
    <str>Some string blah blah 292/2017 - more of terms, blah blah</str>
    <str>Something else, blah blah</str>
</arr>

这是我的 terms_txt 字段的 solr 架构字段配置(字段是动态的):

<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-FoldToASCII.txt"/>          
    <charFilter class="solr.HTMLStripCharFilterFactory"/>
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(^|\s)([^\-\_&amp;\s]+([\-\_&amp;]+[^\-\_&amp;\s]*)+)(?=(\s|$))" replacement="$1MжџљМ$2 $2" />
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\bMжџљМ([^\s]*?)\b[\-_&amp;]+" replacement="MжџљМ$1" />
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\bMжџљМ([^\s]*?)\b[\-_&amp;]+" replacement="MжџљМ$1" />
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\bMжџљМ([^\s]*?)\b[\-_&amp;]+" replacement="MжџљМ$1" />
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="MжџљМ" replacement="" />
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(\w)&amp;(\w)" replacement="$1and$2" />
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LengthFilterFactory" min="3" max="99"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\b[\-_]+\b" replacement="" />
    <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-FoldToASCII.txt"/>
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(\w)&amp;(\w)" replacement="$1and$2" />
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LengthFilterFactory" min="3" max="99"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
    <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.RemoveDuplicatesTokenFilterFactory" />
  </analyzer>
</fieldType>

有人知道我应该如何允许像 .-/这样的特殊字符可搜索吗?您能发现我的示例中的一些缺陷或提出更好的解决方案吗?

最佳答案

您应该首先查看内容分析页面告诉您的内容 - 我的猜测是 StandardTokenizer 在标记化时会删除许多特殊字符(并且您的 PatternReplaces 也可能会删除内容)。

空白分词器更适合匹配特殊字符很重要的字段,因为它只会中断并删除空白。

定义不同的字段并为这些字段使用不同的分词器,然后根据权重对这些字段中的命中进行优先级排序。不要试图让一个字段满足您的所有查询需求,而是创建多个字段 - 每个定义一个字段并查询多个字段。您可以将 qf 与 (e)dismax 处理程序一起使用来调整权重。这些处理程序还允许您增强两个和三个带状疱疹的短语匹配。

使用一个或多个 copyField 指令将内容从一个字段获取到其他字段,这样您就不必更改索引代码来调整 Solr 中的调整方式。

如果将 debugQuery=true 附加到查询字符串,您还可以看到 Solr/Lucene 如何计算每个文档的分数以及影响其排名的因素,因此您可以调整评分值并查看最终分数到底如何变化。

编写查询时,请使用 \ 转义任何特殊字符。

关于search - 如何使 SOLR 查询语法中的字符可搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47532982/

相关文章:

search - 根据嵌套字段值修改elasticsearch分数

php - 异步搜索事件处理

java - 如何按属性搜索对象数组 (Java)

ruby-on-rails - 如何使用 rails sunspot 在 solr 中加入模型

java - Lucene MoreLikeThis.like(fieldName, reader) 中 "fieldName"的用途是什么?

search - Elasticsearch索引备份选项

database - 分面搜索 : ElasticSearch/Solr or a simple database query?

lucene - Solr/Lucene : What is the difference between regular queries and filter queries

grails - 将 grails 应用程序升级到 2.3.7 时出错

java - 异步构建 Hibernate Search 索引以确保不会停机。