使用太阳黑子Solr搜索部分电话号码



我正在使用太阳黑子Solr搜索引擎开发rails应用程序,我需要在Solr 4.1中索引电话号码。

例如,如果我的电话号码为"+12 (456) 789-0101",则我的页面应由查询建立:

  • +12 (456) 789-0101 (正确格式的电话)
  • +12 (456) 789... (手机左侧格式正确)
  • .......(456) 789-0101(正确格式的电话右侧)
  • .......(456) 789......... (正确格式的手机中间部分)

  • 124567890101(仅带号码的完整电话)

  • 1245678........... (手机左边部分有连环号码)
  • ............890101(带有串联号码的电话右侧)
  • ......567890......(电话中间部分,带连线号码)

我知道我可以使用:

  • EdgeNGramFilterFactory用于将手机拆分为NGrams(正面和背面)
  • WordDelimiterFilterFactory用于连接号码和拆分电话以进行零件。

所以,我做了什么:

  1. shema.xml中创建新的 Solr 字段类型:

    <fieldType name="phone_number" class="solr.TextField"> <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="20" side="front"/> <filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="20" side="back"/> </analyzer> </fieldType>

    <dynamicField name="*_phone" stored="false" type="phone_number" multiValued="true" indexed="true"/>

  2. 将可搜索的电话字段定义为"*_phone"类型:

    string :work_phone, :as => :work_phone, :stored => true do work_phone.gsub(/D/, '') if work_phone end

    string :mobile_phone, :as => :mobile_phone, :stored => true do mobile_phone.gsub(/D/, '') if mobile_phone end

  3. 运行重新索引:

    bundle exec rake sunspot:rebuild

    但是当重新索引完成后它不起作用,我只能找到使用查询搜索的结果:"完整电话"和"手机左侧"。使用"手机中间部分"和"手机右侧"搜索不会给我任何结果。

我做错了什么吗?如何使手机部分正确灼热?请帮忙。谢谢!

(仅评论Solr部分,不确定SunSpot如何映射它)

这里有几件事不太对劲:

  1. 自 Solr 4.4 以来,side=back 不再是一个选项,因此您可能只会获得同一过滤器的两个副本
  2. 无论如何,拥有同一过滤器的两个副本是不好的,因为第二个副本将查看第一个过滤器发布的所有令牌,事情会变得混乱。

这是匹配后缀的好方法,考虑到剥离所有随机的非数字内容和索引/查询的不对称性(来自我的AirPair Solr教程):

<fieldType name="phone" class="solr.TextField">
  <analyzer type="index">
    <tokenizer class="solr.KeywordTokenizerFactory" />
    <filter class="solr.PatternReplaceFilterFactory" pattern="([^0-9])" replacement="" replace="all"/>
    <filter class="solr.ReverseStringFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="30"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.KeywordTokenizerFactory" />
    <filter class="solr.PatternReplaceFilterFactory" pattern="([^0-9])" replacement="" replace="all"/>
    <filter class="solr.ReverseStringFilterFactory"/>
  </analyzer>
</fieldType>

请注意,这对于使用默认分析器包含空格的查询没有帮助,因为它们将在命中字段分析之前在空间上分解。如果您知道您正在搜索电话号码,则可以引用搜索字符串或切换到其他(可能是字段)查询分析器。

如果你确实想匹配中间,也许你不想要这些,只想要NGram,而不是EdgeNGram分析。

Ectualy,这是我的代码,它有效:

架构.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"/>

和红宝石代码:

  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

最新更新