我试图在包含名称的字段上执行搜索。我试图找出为什么我不能用撇号查询名称。如果我搜索" O'",我会得到我期望的结果(例如O' Brien,O' Farrell,O' Connell等)。如果我搜索名字" O' Brien",我会得到我期望的结果。但是,如果我搜索" O' B"或者除了全名或者只是" O'",我没有结果。 仅供参考,在前面的例子中,我实际上并未包括双引号。有问题的字段使用以下字段类型(创建自定义类型以确保我可以搜索以y结尾的名称 - 没有它,我无法找到" Icy"):
<fieldType name="trname" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<!-- in this example, we will only use synonyms at query time
<filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
-->
<!-- Case insensitive stop word removal.
enablePositionIncrements=true ensures that a 'gap' is left to
allow for accurate phrase queries.
-->
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
format="wordset"
/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
</fieldType>
非常感谢任何帮助。
编辑:我刚刚注意到问题的标题是完全错误的!
答案 0 :(得分:1)
使用通配符查询时,大多数分析都不会发生 - 这意味着您搜索的标记与查询时的标记不同。
WordDelimiterFilter将根据'
分割标记,这意味着当您为内容编制索引时,您将为单词的每个部分获取单独的标记 - 即O
和Brien
。在您搜索时,不会发生这种拆分,Lucene会尝试将单个令牌 - O'Brien
与已编入索引的令牌进行匹配。由于没有令牌匹配O'Brien
(因为在索引时术语被拆分为多个令牌),所以不会受到影响。
解决方案是创建一个与您期望使用的通配符匹配的字段 - 在这种情况下,可能只是一个包含WhitespaceTokenizer和LowercaseFilter的字段(它应该与通配符一起使用,因为它是多重软件)。
预计会使用具有相同内容的多个不同字段,您可以使用copyField
确保将相同的内容编入多个字段,然后根据您要查询的方式进行不同的处理。这样,当您希望Brien与O'Brien匹配时,您可以搜索一个字段,并且可以使用一个字段进行通配符搜索,可能不是这种情况。