我的索引中有一些项目(Solr )。( 4.4),其中包含像Foobar 135g这样的名称,其中135 g引用了一些权重。搜索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's来搜索foob和bar或obar (出现在项目名称末尾的字符串)。首先,我认为它与WordDelimiterFilterFactory和catenateWords选项有关。但这个选项与其中的数字无关(对吗?)
在阅读了文档(http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters)之后,我找到了默认为1的generateNumberParts。这导致将135g拆分为135和g。但是,只要启用了preserveOriginal选项,135g也会被索引为一个完整的字符串。管理界面中的Analysis面板也显示了这一点:

有谁知道什么样的过滤器,记号器..。是造成这个问题的原因吗?
更新
我发现了一些有趣的东西。在调试搜索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,字符串被分割成这部分。但是,为什么Solr要将其转换为MultiPhraseQuery呢?我现在有点困惑,我认为solr.WordDelimiterFilterFactory在查询时生成的每个令牌都会触发单独的搜索(或者至少在令牌之间触发一个OR语句)。
拜托,有人理清了我的想法,我有点糊涂了;)我怎么才能避免这种情况呢?
发布于 2014-01-02 14:22:36
这是WordDelimiterFilterFactory。您应该能够在您的管理面板中看到它的分析。若要不这样做,请使用: splitOnNumerics="0“作为属性。
更新:
在这里阅读更多关于它的信息:http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters。
solr.WordDelimiterFilterFactory
创建solr.analysis.WordDelimiterFilter。
将单词拆分为子词,并对子字组执行可选转换。默认情况下,单词被拆分为具有以下规则的子单词:
splitOnNumerics="1“导致字母表=>数字转换生成一个新的Solr1.3部分:"j2se”=> "j“"2”"se“默认值为true ("1");设置为0以关闭
更新2
根据你最近的评论,我现在明白了你的意思。我采用了您的字段类型定义,并在solr4.5.1上用您的句子进行索引,并能够搜索test_mytext:"foobar 135 g“、test_mytext:foobar 135 g、test_mytext:foobar 135 g、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 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":“n 0.8563627=(匹配)乘积:\n 1.141817 =(匹配)和:\n 0.35407978 =(匹配)权重(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 =tf(docFreq=2,maxDocs=36)\n 0.13194223 = queryNorm\n 0.77006286 = fieldWeight in 1,乘积为:n 1.4142135 = tf(freq=2.0),freq为: 2.0 = termFreq=2.0\n 3.4849067 =termFreq=2.0\n 3.4849067(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 =以国防军(docFreq=2,maxDocs=36)\n 0.13194223 = queryNorm\n 0.94313055 = fieldWeight in 1,乘积为:n 1.7320508 = tf(freq=3.0),freq为:\n 3.0 = termFreq=3.0\n 3.4849067 =国防军(docFreq=2,maxDocs=36) 0.15625 = fieldNorm(doc=1)\n 0.35407978 =(匹配)重量(test_mytext:135g in 1) DefaultSimilarity,结果为:\n 0.35407978 =分数(doc=1,freq=2.0 = termFreq=2.0\n),乘积为:N 3.4849067 =国防军(docFreq=2,maxDocs=36) 0.13194223 = queryNorm\n 0.77006286 = fieldWeight in 1,乘积为:n 1.4142135 = tf(freq=2.0),freq为: 2.0 = termFreq=2.0\n 3.4849067 =docFreq=2,maxDocs=36)\n 0.15625 = fieldNorm(doc=1)\n 0.75 =coord(3/4)\n },
我正在使用solr 4.5.1。
更新4然后我注意到您正在使用Solr4.4.0。我获取了您的字段定义和短语,并运行了一个查询,它会找到您的结果。
查询=> name_texts:“135 g”
结果:
<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>您的处理看起来是正确的,它在我的实例中找到了结果。我最初以为你有额外的东西,但在我的本地例子中似乎没有引起问题。查找这些问题的最佳位置是使用管理分析页面和调试查询,您已经在这样做了。我想不出还有什么别的东西,因为我无法复制。帮你自己一个忙,只需为字段定义更改为schema.xml的solr实例,并通过管理面板(documents) => {"id":"100“、”name_texts“:”Foobar135g“}对其进行索引。运行此查询http://localhost:8983/solr/collection1/select?q=name_texts%3A%22135g%22&wt=xml&indent=true&debugQuery=true
https://stackoverflow.com/questions/20884338
复制相似问题