使用Sunspot Solr搜索电话号码的一部分
我正在用sunspot Solr搜索引擎开发rails应用程序,我需要在Solr 4.1中索引电话号码 例如,如果我有电话号码“+12(456)789-0101”,我的页面应通过以下查询建立:使用Sunspot Solr搜索电话号码的一部分,solr,sunspot,solr4,sunspot-rails,sunspot-solr,Solr,Sunspot,Solr4,Sunspot Rails,Sunspot Solr,我正在用sunspot Solr搜索引擎开发rails应用程序,我需要在Solr 4.1中索引电话号码 例如,如果我有电话号码“+12(456)789-0101”,我的页面应通过以下查询建立: +12(456)789-0101(电话格式正确) +12(456)789。。。。。。。。。(手机左侧部分格式正确) …….(456)789-0101(手机右侧部分格式正确) ……456)789。。。。。。。。。(手机中部格式正确) 124567890101(仅带号码的完整电话) 1245678。。。。。
- +12(456)789-0101(电话格式正确)
- +12(456)789。。。。。。。。。(手机左侧部分格式正确)
- …….(456)789-0101(手机右侧部分格式正确)
- ……456)789。。。。。。。。。(手机中部格式正确)
- 124567890101(仅带号码的完整电话)
- 1245678。。。。。。。。。。(电话的左半部分带有链接号码)
- 890101(电话的右侧部分,带有连网号码)
- ……567890。。。。。。(电话的中间部分带有连网号码)
用于将手机拆分为NGrams(正面和背面)EdgeNGramFilterFactory
用于连接电话号码,拆分电话用于部件李>WordDelimiterFilterFactory
shema.xml
中创建新的Solr字段类型:
string:work\u phone,:as=>:work\u phone,:stored=>true do
工作电话.gsub(/\D/,'')如果是工作电话
结束
string:mobile\u phone,:as=>:mobile\u phone,:stored=>true do
mobile\u phone.gsub(/\D/,'')如果是mobile\u phone
结束
bundle exec rake太阳黑子:重建
但当重新索引完成后,它就不起作用了,我只能通过以下查询找到结果:“完整手机”和“手机的左侧部分”。用“手机中部”和“手机右侧”搜索不会给我任何结果
)查询解析器
如果你真的想匹配中间部分,也许你不想要这些,只想要NGram,而不是EdgeNGram分析 (仅对Solr部分进行评论,不确定太阳黑子如何绘制它)
这里有两件事不太对劲:
自Solr4.4以来,side=back不再是一个选项,因此您可能只得到同一个过滤器的两个副本
拥有同一个筛选器的两个副本无论如何都是不好的,因为第二个副本将查看第一个筛选器发出的所有令牌,事情将变得一团糟
这里是一个匹配后缀的好方法,考虑到剥离所有随机的非数字内容和索引/查询的不对称性(从我的:
)查询解析器
如果你真的想匹配中间部分,也许你不想要这些,只想要NGram,而不是EdgeNGram分析 实际上,这是我的代码,它可以工作:
Schema.xml:
<fieldType class="solr.TextField" name="phone_number" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="20"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.WordDelimiterFilterFactory" catenateNumbers="1"/>
</analyzer>
</fieldType>
<dynamicField name="*_phone" stored="false" type="phone_number" multiValued="false" indexed="true"/>
<dynamicField name="*_phones" stored="false" type="phone_number" multiValued="false" indexed="true"/>
实际上,这是我的代码,它可以工作:
Schema.xml:
<fieldType class="solr.TextField" name="phone_number" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="20"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.WordDelimiterFilterFactory" catenateNumbers="1"/>
</analyzer>
</fieldType>
<dynamicField name="*_phone" stored="false" type="phone_number" multiValued="false" indexed="true"/>
<dynamicField name="*_phones" stored="false" type="phone_number" multiValued="false" indexed="true"/>
谢谢所以,据我所知,我只需要使用NgramFilterFactory和PatternReplaceFilterFactory来获得预期的结果。我需要从查询中删除空格和其他非数字符号吗?请给我Ngram factory的examle以作为查询进行搜索:格式正确的手机,只带数字的手机以及左/中/右部分(带空格和不带空格,“-”,“+”)。谢谢你!我没有。但我认为你应该试着用普通的边缘过滤器来代替边缘过滤器,看看这样做是否奏效。最糟糕的情况是,你可以将字段复制到另一个字段并搜索这两个字段。谢谢!所以,据我所知,我只需要使用NgramFilterFactory和PatternReplaceFilterFactory来获得预期的结果。我需要从查询中删除空格和其他非数字符号吗?请给我Ngram factory的examle以作为查询进行搜索:格式正确的手机,只带数字的手机以及左/中/右部分(带空格和不带空格,“-”,“+”)。谢谢你!我没有。但我认为你应该试着用普通的边缘过滤器来代替边缘过滤器,看看这样做是否奏效。最坏的情况是,您可以将字段复制到另一个字段并同时搜索这两个字段。
text :work_phone
text :work_phone_parts, :as => :work_phone do
"00#{work_phone.gsub(/\D/, '')}" if work_phone
end
text :mobile_phone
text :mobile_phone_parts, :as => :mobile_phone do
"00#{mobile_phone.gsub(/\D/, '')}" if mobile_phone
end