SOLR Haystack 拆分数字

SOLR Haystack splitting numerics

下面的问题与使用 SOLR (4.9.0) 和 Haystack 的 Django 应用程序 (1.8.8) 有关。

我要查找的数据包含"A1234"、"ABCDE1"等各种字符串;这些字符串将出现在 "text" 和 "name" 字段中,定义如下:

name = indexes.CharField(indexed=True, model_attr="name")
text = indexes.EdgeNgramField(document=True, use_template=True)

如果在文本字段中搜索上述字符串之一,则不会找到它,但在名称字段中搜索没有问题。如果我在文本字段中搜索时省略了字母(例如,我搜索“1234”),那么我可以找到我要查找的内容。

在启用调试的情况下直接查询 SOLR 服务器显示这些字符串被拆分:

// text field - no hits
rawquerystring: "A1234",
querystring: "A1234",
parsedquery: "+text:a +text:1234",
parsedquery_toString: "+text:a +text:1234",
explain: { },
QParser: "LuceneQParser",

// name field - finds the correct records
rawquerystring: "name:A1234",
querystring: "name:A1234",
parsedquery: "name:a1234",
parsedquery_toString: "name:a1234",
explain: { },
QParser: "LuceneQParser",

schema.xml 与 edge_ngram 字段相关的部分(上面的文本字段就是这样)如下:

<fieldType name="edge_ngram" class="solr.TextField" positionIncrementGap="1">
  <analyzer type="index">
    <tokenizer class="solr.NGramTokenizerFactory" minGramSize="3" maxGramSize="15"/>
    <filter class="solr.LowerCaseFilterFactory" />
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1"        generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="
0" splitOnCaseChange="1" splitOnNumerics="0"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory" />
    <filter class="solr.LowerCaseFilterFactory" />
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
  </analyzer>
</fieldType>

那么,有什么办法可以防止这些字符串的分裂吗?我原以为 splitOnNumerics="0" 选项可以解决问题(如 Solr: Can't search for numbers mixed with characters 中所建议),但似乎不能应用于 solr.EdgeNGramFilterFactory。我使用了后一个工厂,因为它解决了另一个问题,即搜索 "foo bar" 不会在文本字段中找到 "foobar.com"(用户将 运行 这种搜索并期待成功).

有人对解决这个问题有什么建议吗?

终于找到了。 edge_ngram 字段类型包含:

  <tokenizer class="solr.WhitespaceTokenizerFactory" />                                                                                              
    <filter class="solr.LowerCaseFilterFactory" />                                                                                                   
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/> 

修改 WordDelimiterFilterFactory 以设置 generateNumberParts="0" 可以解决问题,同时保留该字段的其他要求。