我的索引中有一些项目(Solr。4.4),其中包含诸如Foobar 135g
之类的名称,其中135g表示某些重量。搜索foobar
或foobar 135
确实可以,但是当我尝试搜索确切的短语foobar 135g
时,什么也没找到。
我在solr管理面板“ Analysis”中分析了查询。这里的一切看起来都很好。正确地索引了字段,正确地拆分了查询,并且我得到了点击(由标记上的紫色背景指示)。
但是在索引和/或查询时间上处理字符串的方式一定存在问题。这是字段定义,我正在使用:
<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
语句)。拜托,有人让我头脑清醒,我有点困惑;)我怎样才能避免这种情况?
最佳答案
它是WordDelimiterFilterFactory。您应该可以在分析中的管理面板中看到它。为此,请使用:splitOnNumerics =“ 0”作为属性。
更新:
在这里阅读有关它的更多信息:http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters。
solr.WordDelimiterFilterFactory
创建solr.analysis.WordDelimiterFilter。
将单词拆分为子单词,并对子单词组执行可选的转换。默认情况下,单词会按照以下规则分为子单词:
splitOnNumerics =“ 1”导致字母=>数字过渡以生成新零件[Solr 1.3]:
“ j2se” =>“ 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
这是我的调试日志,带有您的字段定义,而不是要求您查看完全不同的处理的原因:
查询=> test_mytext:135g
调试”:{
“ 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),频率为:\ n 2.0 = termFreq = 2.0 \ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n 0.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 =期限频率= 3.0 \ n 3.4849067 = idf(docFreq = 2,maxDocs = 36)\ n 0.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 =字段权重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 =坐标(3/4)\ n“
},
我正在使用solr 4.5.1。
更新4
然后我注意到您正在使用Solr 4.4.0。我使用了您确切的字段定义和短语,并进行了查询,它找到了您的结果。
查询=> name_texts:“ 135g”
结果:
<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>
您的处理看起来正确,并且在我的实例中找到了结果。我首先以为你还有
,但看起来并没有在我的本地实例中引起问题。查找这些问题的最佳位置是使用admin分析页面和调试查询,您已经在执行此操作。我无法想到其他任何东西,因为我无法复制。通过仅使用solr的干净实例,而对字段定义仅更改schema.xml并通过管理面板(文档)对此进行索引,即可帮自己一个忙=> {“ id”:“ 100”,“ name_texts”:“ Foobar 135g“}。运行此查询
http://localhost:8983/solr/collection1/select?q=name_texts%3A%22135g%22&wt=xml&indent=true&debugQuery=true
关于solr - Solr:无法搜索包含字符的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20884338/