我在 Solr/Lucene (3.x) 中有一个带有特殊副本字段 facet_headline 的文档,以便有一个用于分面的非词干字段。
有时两个或更多的词属于一个词,这应该作为一个词处理/计数,例如“kim jong il”。
所以标题“星期六:金正日死了”应该分成:Saturday
kim jong il
had
died
出于这个原因,我决定使用 protected 词 (protwords),并在其中添加 kim jong il
。schema.xml
看起来像这样。
<fieldType name="facet_headline" class="solr.TextField" omitNorms="true">
<analyzer>
<tokenizer class="solr.PatternTokenizerFactory" pattern="\?|\!|\.|\:|\;|\,|\"|\(|\)|\\|\+|\*|<|>|([0-31]+\.)" />
<filter class="solr.WordDelimiterFilterFactory" splitOnNumerics="0"
protected="protwords.txt" />
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.TrimFilterFactory"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
enablePositionIncrements="true"
/>
</analyzer>
</fieldType>
使用 solr 分析它看起来不起作用!
该字符串仍被拆分为 6 个单词。看起来 protword.txt 没有被使用,但如果标题只包含名称:
kim jong il
一切正常,术语不会被拆分。有没有办法达到我的目标:不拆分特定的词/词组?
最佳答案
这就是我认为正在发生的事情。WordDelimiterFilterFactory
是一个标记过滤器,所以它的工作是添加、删除或更改已经生成的标记,(在这种情况下,根据大小写转换、连字符等将单词拆分为子单词),而不是将文档拆分为单词,这是分词器的工作(在本例中为 PatternTokenizerFactory
)。似乎您的标记器缺少 \s
,因此它不会拆分单词并且 WordDelimiterFilterFactory
正在获取整个短语。
在您的示例中,WordDelimiterFilterFactory
将获得整个短语 Saturday kim jong il had died
,并且由于它与您的任何 protected 单词都不匹配,因此它会继续将此“单词”拆分为子单词(空格是非字母数字字符,因此词有资格进行拆分)。
所以这是一个可能的解决方案。将 \s
添加到您的标记器模式,然后使用 KeywordMarkerFilterFactory 来保护您的话。像这样的东西:
<fieldType name="facet_headline" class="solr.TextField" omitNorms="true">
<analyzer>
<tokenizer class="solr.PatternTokenizerFactory" pattern="\s|\?|\!|\.|\:|\;|\,|\"|\(|\)|\\|\+|\*|<|>|([0-31]+\.)" />
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"
ignoreCase="false"/>
<filter class="solr.WordDelimiterFilterFactory" splitOnNumerics="0" />
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.TrimFilterFactory"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
enablePositionIncrements="true"
/>
</analyzer>
</fieldType>
更新 :好的,现在我仔细检查了文档,这个提议的解决方案不太可能适合你。我将专注于试验 SynonymFilterFactory 。在 solr-user 邮件列表中检查 this message。它有点过时,但提供了对问题的一些见解。