Java Solr通配符搜索结果不正确
在进行通配符查询时,出现了一些意外的结果。我正在使用Solr6.6.0。solr ui中的eDiscoveryMax处理程序。以下查询按预期返回不带通配符的结果-firstNames:James,但添加通配符时未找到任何结果。 对于firstNames字段,我使用默认的fieldType text_en和默认的标记器和过滤器。当我对firstNames:Stephen和firstNames:Stephen*运行完全相同的查询时,我得到了通配符搜索和非通配符搜索的结果。下面是schema.xml中的字段xml:Java Solr通配符搜索结果不正确,java,solr,tokenize,Java,Solr,Tokenize,在进行通配符查询时,出现了一些意外的结果。我正在使用Solr6.6.0。solr ui中的eDiscoveryMax处理程序。以下查询按预期返回不带通配符的结果-firstNames:James,但添加通配符时未找到任何结果。 对于firstNames字段,我使用默认的fieldType text_en和默认的标记器和过滤器。当我对firstNames:Stephen和firstNames:Stephen*运行完全相同的查询时,我得到了通配符搜索和非通配符搜索的结果。下面是schema.xml中
<field name="firstNames" type="text_en" multiValued="true" indexed="true" stored="true"/>
当您执行通配符查询时,不会调用分析链(这是一个小谎言——确实如此,但仅限于MultiTermAware组件——这通常意味着LowercaseFilter是唯一仍然处于活动状态的组件) 由于您有一个词干过滤器和所有格过滤器,因此
James
上的ends
将被删除。由于这只发生在索引时间(请记住,当您使用通配符时,通常会在查询时跳过分析链),因此标记jame
存储在索引中
当您进行查询时,firstNames:James*
,您要求Solr“查找包含以James
开头的令牌的任何文档。由于存储的是令牌jame
,因此没有与James
匹配的令牌
当您使用Stephen
尝试此操作时,词干筛选或所有格筛选都不会删除单词的结尾,因此Stephen*
会查找任何以Stephen
开头的标记,并且由于该标记存在(没有更改),因此会返回匹配项
解决方案取决于您的用例;不需要在名称字段上使用词干或所有格过滤器,因为这对名称没有实际意义(相反,您可以应用自己的逻辑来匹配相似的名称)。另一种选择是使用ngramfilter,有效地为令牌的每个前缀和中缀版本生成令牌(
foo
,f
,fo
,oo
,o
)。关于停止字,对“我是否必须使用停止字”问题的回答不是“是”或“否”。答案是“为什么不”“但要明智地根据你的数据。
对于药物数据库,“a”、“b”、“c”。。。不应在stopwords定义文件中。
对于100%停止词数据库的电影标题,标题字段不能使用停止词,但描述字段可能应该使用。为名字创建2-3个复制字段并进行不同分析是否是一种好方法,这样我就可以匹配准确的搜索词并保留通配符,并猜测通配符匹配的得分会更低。是的,这是一种常见的方法。一个字段用于精确匹配,一个字段用于语音匹配,其他字段用于满足应用程序中的任何要求。需求应该引导必要的领域,而不仅仅是哪些领域可能有用。
<fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
</fieldType>