首页 文章

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

提问于
浏览
1

我有这个问题,我试图解决很长一段时间 . 我不是solr专家,我还在学习它 .

我有一个特殊类型的ID 's in my system, that have to be searchable by users. The problem is, that those ID' s包含一些solr特殊字符 . 顺便说一下,这些ID与 terms_txt 字段中的其他搜索项一起存储 .

一些ID示例: 292/20171.2.61-962-37/2017
第一个我将称为' simple one ',第二个称为 'complex one ' .

从整个互联网上的红色来看,如果我们进行短语搜索,这种搜索应该是可能的 . 因此,如果我们在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>

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

1 回答

  • 1

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

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

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

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

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

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

相关问题