如何使作为SOLR查询语法一部分的字符可搜索?

时间:2017-11-28 13:38:27

标签: 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>

这是我对term_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>

任何人都有任何线索我应该如何允许像.- /这样的特殊字符进行搜索?你能发现我的例子中的一些缺陷或建议更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

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

Whitespace Tokenizer更适合匹配特殊字符很重要的字段,因为它只会打破并删除空格。

定义不同的字段并为这些字段使用不同的标记器,然后根据权重确定这些字段中的匹配优先级。而不是尝试使一个字段满足您的所有查询需求,而是创建多个字段 - 每个字段定义一个并查询多个字段。您可以使用qf和(e)dismax处理程序一起调整权重。这些处理程序还允许您增加两个和三个带状疱疹的短语匹配。

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

如果您将debugQuery=true附加到查询字符串,您还可以看到Solr / Lucene如何计算每个文档的得分以及对其排名的贡献,因此您可以调整评分值并确切了解最终得分变化。

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