Solr:使用 EdgeNGramFilterFactory 的精确短语查询

标签 solr tokenize phrase

在 Solr (3.3) 中,是否可以通过 EdgeNGramFilterFactory 逐个字母地搜索字段?并且对短语查询也很敏感?

例如,我正在寻找一个字段,如果包含“contrat informatique”,则会在用户键入时找到该字段:

  • 契约(Contract)
  • 信息
  • 控制
  • 信息
  • "contrat informatique"
  • "联系信息"

  • 目前,我做了这样的事情:
    <fieldtype name="terms" class="solr.TextField">
        <analyzer type="index">
            <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
            <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
            <tokenizer class="solr.LowerCaseTokenizerFactory"/>
            <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
        </analyzer>
        <analyzer type="query">
            <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
            <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
            <tokenizer class="solr.LowerCaseTokenizerFactory"/>
        </analyzer>
    </fieldtype>
    

    ...但它在短语查询上失败了。

    当我查看 solr admin 中的模式分析器时,我发现“contrat informatique”生成了以下标记:
    [...] contr contra contrat in inf info infor inform [...]
    

    因此查询适用于“contrat in”(连续标记),而不适用于“contrat inf”(因为这两个标记是分开的)。

    我很确定任何类型的词干提取都可以用于短语查询,但是在 EdgeNGramFilterFactory 之前我找不到要使用的正确过滤器标记器.

    最佳答案

    默认情况下,由于查询 slop 参数 = 0,精确短语搜索不起作用。
    搜索短语 '"Hello World"' 它搜索具有连续位置的术语。
    我希望 EdgeNGramFilter 有一个参数来控制输出定位,这看起来像一个旧的 question .

    通过将 qs 参数设置为某个非常高的值(超过 ngram 之间的最大距离),您可以恢复短语。这部分解决了允许短语但不准确的排列的问题。
    因此,搜索“contrat informatique”将匹配诸如“...contract disabled. Informatique...”之类的文本

    enter image description here

    支持精确我最终使用的短语查询 separate fields for ngrams .

    所需步骤:

    定义单独的字段类型来索引常规值和克数:

    <fieldType name="text" class="solr.TextField" omitNorms="false">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>
    
    <fieldType name="ngrams" class="solr.TextField" omitNorms="false">
      <analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>
    

    告诉 solr copy fields索引时:

    您可以为每个字段定义单独的 ngrams 反射:
    <field name="contact_ngrams" type="ngrams" indexed="true" stored="false"/>
    <field name="product_ngrams" type="ngrams" indexed="true" stored="false"/>
    <copyField source="contact_text" dest="contact_ngrams"/>
    <copyField source="product_text" dest="product_ngrams"/>
    

    或者您可以将所有 ngram 放入一个字段:
    <field name="heap_ngrams" type="ngrams" indexed="true" stored="false"/>
    <copyField source="*_text" dest="heap_ngrams"/>
    

    请注意,在这种情况下,您将无法分离助推器。

    最后一件事是在查询中指定 ngrams 字段和助推器。
    一种方法是配置您的应用程序。
    另一种方法是在 solrconfig.xml 中指定“附加”参数
       <lst name="appends">
         <str name="qf">heap_ngrams</str>
       </lst>
    

    关于Solr:使用 EdgeNGramFilterFactory 的精确短语查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7612889/

    相关文章:

    bash - Bash 如何对脚本进行标记?

    使用 Solr 搜索和匹配短语的计数

    java - 具有单个或多个值的 SOLR 查询字段

    solr - 将字段设置为默认搜索字段

    Solr 未加载自定义过滤器

    Elasticsearch 过滤器中的短语匹配

    nlp - 如何在 Stanford CoreNLP 中获取短语标签?

    solr - 重新加载SolrCloud配置(存储在Zookeeper中)-schema.xml

    sql - Oracle中将字符串拆分为多行

    python - if 形式出现异常 : TypeError: unhashable type: 'list' in Python nltk