Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Sunspot Solr搜索电话号码的一部分_Solr_Sunspot_Solr4_Sunspot Rails_Sunspot Solr - Fatal编程技术网

使用Sunspot Solr搜索电话号码的一部分

使用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。。。。。

我正在用sunspot 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
    用于连接电话号码,拆分电话用于部件
因此,我所做的是:

  • 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太阳黑子:重建

    但当重新索引完成后,它就不起作用了,我只能通过以下查询找到结果:“完整手机”和“手机的左侧部分”。用“手机中部”和“手机右侧”搜索不会给我任何结果

  • 我做错什么了吗?如何使手机部件正确烧焦? 请帮忙。谢谢

    (仅对Solr部分进行评论,不确定太阳黑子如何绘制它)

    这里有两件事不太对劲:

  • 自Solr4.4以来,side=back不再是一个选项,因此您可能只得到同一个过滤器的两个副本
  • 拥有同一个筛选器的两个副本无论如何都是不好的,因为第二个副本将查看第一个筛选器发出的所有令牌,事情将变得一团糟
  • 这里是一个匹配后缀的好方法,考虑到剥离所有随机的非数字内容和索引/查询的不对称性(从我的:

    
    )查询解析器

    如果你真的想匹配中间部分,也许你不想要这些,只想要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