我正在尝试对存储的值(而不是查询值)执行完全匹配。
我的索引数据类似于:“香蕉共和国”
我需要以下查询才能匹配:
这些不匹配:
使用类似于query_string LIKE '%stored_val%'
的查询,我的方案实际上很简单,很容易使用SQL,但我无法配置anlayzers来执行它。我确信EdgeNGramFilter
可以实现这一点,但创建长度超过30个字符的ngram将非常昂贵。
我当前的实施:在索引分析器中,使用solr.KeywordTokenizerFactory
。在查询分析器中,使用solr.ShingleFilterFactory
(2-4个令牌)。使用分析工具时,一切看起来都很好。但是使用查询API,查询将转换为:
rawquerystring: "match_name:"banana republic"",
parsedquery_toString: "match_name:"(banana bananarepublic) republic""
与我存储的令牌“bananarepublic”不匹配
我的分析链看起来像:
<fieldType name="singletoken" class="solr.TextField">
<analyzer type="index">
<charFilter class="solr.MappingCharFilterFactory" mapping="../../common-config/mapping-ISOLatin1Accent.txt"/> <!-- map accented letters to their ascii equivilants -->
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.PatternReplaceFilterFactory" pattern="[^A-Za-z0-9& ]" replacement=" "/>
<filter class="solr.PatternReplaceFilterFactory" pattern="(^\s+|\s+$)" replacement=""/> <!-- join everything in a single token with no spaces -->
</analyzer>
<analyzer type="query">
<charFilter class="solr.MappingCharFilterFactory" mapping="../../common-config/mapping-ISOLatin1Accent.txt"/> <!-- map accented letters to their ascii equivilants -->
<tokenizer class="solr.WhitespaceTokenizerFactory" />
<filter class="solr.WordDelimiterFilterFactory" /> <!-- using all default options from: https://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.WordDelimiterFilterFactory -->
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.PatternReplaceFilterFactory" pattern="[^A-Za-z0-9& ]" replacement=" "/>
<filter class="solr.TrimFilterFactory" />
<filter class="solr.ShingleFilterFactory" minShingleSize="2" maxShingleSize="4" outputUnigrams="true" tokenSeparator="" />
</analyzer>
</fieldType>
答案 0 :(得分:0)
在4.x和trunk中,mm的默认值由q.op param决定(q.op = AND =&gt; mm = 100%; q.op = OR =&gt; mm = 0%)。请记住,默认运算符受schema.xml条目的影响。在旧版本的Solr中,默认值为100%(所有子句必须匹配)
您是否在查询中使用了这种语法?
your_domain替换:8983 / solr的/选择/ Q =香蕉+共和国&安培; DEFTYPE = dismax&安培; q.op = AND&安培; ...
OR
your_domain替换:8983 / solr的/选择/ Q =香蕉+共和国&安培; DEFTYPE = dismax&安培;毫米= 100%&安培; ...
答案 1 :(得分:0)
如果不诉诸自定义query Tokenizers
,就无法解决此问题,因为问题在于标记化阶段。
假设我们有这句话:banana republic
我们想索引和查询这个确切的短语。
实际发生的是:
索引时间:当solr建立索引banana republic
时,tokenizer会将此短语拆分为两个单独的短语,以便索引看起来像这样
短语:banana
短语:republic
查询时间:
在查询时,您还将搜索由OR
操作加入的两个单独的短语。
你真正需要的是这样的东西:
索引:短语:banana republic
作为一个标记。
查询:搜索词组:banana republic
作为一个令牌。
最好的解决方案是使用is来使用像这样的自定义短语标记:https://github.com/lucidworks/auto-phrase-tokenfilter