我有这个问题,我已经尝试解决很长一段时间了。我不是solr专家,我还在学习它。
我的系统中有一种特殊类型的 ID,用户必须可以搜索它。问题是,这些 ID 包含一些 solr 特殊字符。顺便说一下,这些 ID 与其他搜索词一起存储在 terms_txt
字段中。
一些 ID 示例:292/2017
和 1.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)([^\-\_&\s]+([\-\_&]+[^\-\_&\s]*)+)(?=(\s|$))" replacement="$1MжџљМ$2 $2" />
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\bMжџљМ([^\s]*?)\b[\-_&]+" replacement="MжџљМ$1" />
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\bMжџљМ([^\s]*?)\b[\-_&]+" replacement="MжџљМ$1" />
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\bMжџљМ([^\s]*?)\b[\-_&]+" replacement="MжџљМ$1" />
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="MжџљМ" replacement="" />
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(\w)&(\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)&(\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/