我的索引中有一些项目(Solr.4.4),其中包含Foobar 135g
这样的名称,其中135g指的是一些权重。搜索foobar
或foobar 135
确实有效,但当我尝试搜索确切的短语foobar 135g
时,找不到任何内容。
我在solr管理面板“分析”中分析了查询。这里一切都很好看。这些字段被正确编入索引,查询被正确分割,并且我得到了点击(由令牌上的紫色背景表示)。
但是我在索引和/或查询时处理字符串的方式必然存在问题。所以这是字段定义,我正在使用:
<fieldType name="text" class="solr.TextField" omitNorms="false">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StandardFilterFactory"/>
<filter class="solr.WordDelimiterFilterFactory" catenateWords="1" catenateAll="1" preserveOriginal="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="30"/>
<filter class="solr.ReverseStringFilterFactory" />
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="30"/>
<filter class="solr.ReverseStringFilterFactory" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StandardFilterFactory"/>
<filter class="solr.WordDelimiterFilterFactory" catenateWords="1" catenateAll="1" preserveOriginal="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
我正在使用ReverseStringFilterFactory
的两个EdgeNGramFilterFactory
来搜索foob
和bar
或obar
(出现在项目名称末尾的字符串)。首先我想,它与WordDelimiterFilterFactory
和catenateWords
选项有关。但是这个选项对数字没有任何作用(我是对的吗?)。
阅读完文档(http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters)后,我发现generateNumberParts
的默认值为1
。这导致135g
分为135
和g
。但只要我启用了preserveOriginal
选项,135g
也会被编入索引作为整个字符串。这也显示在管理界面的“分析”面板中:
有人知道什么样的过滤器,令牌器......导致了这个问题吗?
更新
我发现了一些有趣的东西。当我调试搜索135g
的查询时,我得到以下调试输出:
<lst name="debug">
<str name="rawquerystring">name_texts:135g</str>
<str name="querystring">name_texts:135g</str>
<str name="parsedquery">MultiPhraseQuery(name_texts:"(135g 135) (g 135g)")</str>
<str name="parsedquery_toString">name_texts:"(135g 135) (g 135g)"</str>
<lst name="explain"/>
<str name="QParser">LuceneQParser</str>
...
</lst>
据我所知,由于前面提到的solr.WordDelimiterFilterFactory
,字符串get被分成了这部分。但是为什么Solr将它转换为MultiPhraseQuery
?我现在有点困惑,我认为solr.WordDelimiterFilterFactory
在查询时生成的每一个令牌都会触发一个单独的搜索(或者至少是令牌之间的OR
语句)。 / p>
拜托,有人清醒了,我有点困惑;)我怎么能避免这个?
答案 0 :(得分:6)
这是WordDelimiterFilterFactory。您应该可以在分析的管理面板中看到它。不要这样做:splitOnNumerics =“0”作为属性。
<强>更新强>
在此处详细了解:http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters。
solr.WordDelimiterFilterFactory
创建solr.analysis.WordDelimiterFilter。
将单词拆分为子词并对子词组执行可选的转换。默认情况下,单词会按照以下规则拆分为子词:
splitOnNumerics =“1”导致alphabet =&gt;数字转换以生成新零件[Solr 1.3]: “j2se”=&gt; “j”“2”“se” 默认为true(“1”);设置为0关闭
更新2
根据您的最新评论,我现在明白您的意思了。我把你的字段类型定义和你的句子索引在solr4.5.1上,并且能够搜索test_mytext:“foobar 135g”,test_mytext:foobar 135g,test_mytext:foobar 135g,test_mytext:foobar,test_mytext:135g,test_mytext:135。其中test_mytext是您在上面的问题中定义的类型。所以我不知道为什么你无法找到你自己的索引。确保您的字段定义如下:<field name="text" type="mytext" indexed="true" stored="true"/>
Upadate 3 这是我的调试日志,带有你的字段定义,而不是为什么你看到完全不同的处理: 查询=&gt; test_mytext:135克 debug“:{ “rawquerystring”:“test_mytext:135g”, “querystring”:“test_mytext:135g”, “parsedquery”:“test_mytext:135g test_mytext:135 test_mytext:g test_mytext:135g”, “parsedquery_toString”:“test_mytext:135g test_mytext:135 test_mytext:g test_mytext:135g”, “解释”:{ “200”:“\ n0.8563627 =(MATCH)乘积:\ n 1.141817 =(MATCH)之和:\ n 0.35407978 =(MATCH)权重(test_mytext:135g in 1)[DefaultSimilarity],结果:\ n 0.35407978 =得分(doc = 1,freq = 2.0 = termFreq = 2.0 \ n),乘积为:\ n 0.45980635 = queryWeight,乘积:\ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n 0.13194223 = queryNorm \ n 0.77006286 = fieldWeight in 1,乘积:\ n 1.4142135 = tf(freq = 2.0),freq为:\ n 2.0 = termFreq = 2.0 \ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n \ n0.15625 = fieldNorm(doc = 1)\ n 0.4336574 =(MATCH)权重(test_mytext:135 in 1)[DefaultSimilarity],结果:\ n 0.4336574 =得分(doc = 1,freq = 3.0 = termFreq = 3.0 \ n),产品:\ n 0.45980635 = queryWeight,产品:\ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n 0.13194223 = queryNorm \ n 0.94313055 = fieldWeight in 1,乘积:\ n 1.7320508 = tf(freq = 3.0),频率为:\ n 3.0 =术语Freq = 3.0 \ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n \ n0.15625 = fieldNorm(doc = 1)\ n 0.35407978 =(MATCH)权重(test_mytext:135g in 1)[DefaultSimilarity],结果:\ n 0.35407978 =得分(doc = 1,freq = 2.0 = termFreq = 2.0 \ n),乘积为:\ n 0.45980635 = queryWeight,乘积:\ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n 0.13194223 = queryNorm \ n 0.77006286 = fieldWeight in 1,乘积:\ n 1.4142135 = tf(freq = 2.0),freq为:\ n 2.0 = termFreq = 2.0 \ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n 0.15625 = fieldNorm(doc = 1)\ n 0.75 = coord(3/4)\ n“ },
我正在使用solr 4.5.1。
更新4 然后我注意到你使用的是Solr 4.4.0。我拿了你确切的字段定义和短语并运行了一个查询,它找到了你的结果。
查询=&gt; name_texts: “135克”
结果:
<result name="response" numFound="1" start="0">
<doc>
<str name="id">100</str>
<str name="name_texts">Foobar 135g</str>
<long name="_version_">1456487722571005952</long></doc>
</result>
<lst name="debug">
<str name="rawquerystring">name_texts:"135g"</str>
<str name="querystring">name_texts:"135g"</str>
<str name="parsedquery">MultiPhraseQuery(name_texts:"(135g 135) (g 135g)")</str>
<str name="parsedquery_toString">name_texts:"(135g 135) (g 135g)"</str>
您的处理看起来正确,并在我的实例中找到结果。我首先以为你有额外的
,但看起来不会导致我的本地实例出现问题。查找这些问题的最佳位置是使用您正在执行的管理分析页面和调试查询。因为我无法再现,所以我想不出任何其他的东西。通过仅仅通过管理面板(文档)=&gt;更改为schema.xml来为您的字段定义和索引获取一个干净的solr实例,帮助自己。 {“id”:“100”,“name_texts”:“Foobar 135g”}。运行此查询http://localhost:8983/solr/collection1/select?q=name_texts%3A%22135g%22&wt=xml&indent=true&debugQuery=true