Solr搜索结果高亮及高级设置

一.高亮简介

  大多数的搜索应用都存在类似的情况,那就是搜索结果显示的屏幕空间有限。如果文档很短并可以在结果列表中显示全部内容,对屏幕空间显示就不会构成太大的问题。但大多数情况下都只能显示每个结果文档的一小部分。这就提出了一个问题:如何决定结果文档中显示哪一部分?理想情况下,应该是基于各片段与用户查询的匹配程度来决定。为查询结果选择最佳片段进行显示,这是Solr高亮框架提供的核心功能。

二.高亮工作原理

  1.基本高亮

  

  请注意,Solr返回的高亮片段在一个单独的元素中:<lst name="highlighting">。因此,客户端应用程序必须处理这些信息,才能对其进行显示。

  2.每个结果生成多个高亮片段

  在某些情况下,每个结果高亮显示一个片段,这可能还不足以为用户提供足够的上下文信息,让用户判断这个结果是否值得进一步研究。使用hl.snippets参数在该文档和结果中的其他文档中梳理出更多的上下文。hl.snippets=2代表允许每个文档最多高亮显示两个片段的显示结果。

  

  正如搜索结果的其他高亮效果那样,设置hl.snippets=2并不能保证每个文档总能生成两个高亮片段。若结果中只有一个满足搜索条件,则只返回一个高亮片段。参数hl.snippets的值应被视为每个结果返回高亮片段的数量上限。

三.查询全流程分析

  

四.高亮内核分析

  solrconfig.xml文件中定义了一个名为highlight的搜索组件,给出了高亮搜索组件的简要定义。

  <!-- Highlighting Component

       http://wiki.apache.org/solr/HighlightingParameters
    -->
  <searchComponent class="solr.HighlightComponent" name="highlight">
    <highlighting>
      <!-- Configure the standard fragmenter -->
      <!-- This could most likely be commented out in the "default" case -->
      <fragmenter name="gap"
                  default="true"
                  class="solr.highlight.GapFragmenter">
        <lst name="defaults">
          <int name="hl.fragsize">100</int>
        </lst>
      </fragmenter>

      <!-- A regular-expression-based fragmenter
           (for sentence extraction)
        -->
      <fragmenter name="regex"
                  class="solr.highlight.RegexFragmenter">
        <lst name="defaults">
          <!-- slightly smaller fragsizes work better because of slop -->
          <int name="hl.fragsize">70</int>
          <!-- allow 50% slop on fragment sizes -->
          <float name="hl.regex.slop">0.5</float>
          <!-- a basic sentence pattern -->
          <str name="hl.regex.pattern">[-\w ,/\n\&quot;&apos;]{20,200}</str>
        </lst>
      </fragmenter>

      <!-- Configure the standard formatter -->
      <formatter name="html"
                 default="true"
                 class="solr.highlight.HtmlFormatter">
        <lst name="defaults">
          <str name="hl.simple.pre"><![CDATA[<em>]]></str>
          <str name="hl.simple.post"><![CDATA[</em>]]></str>
        </lst>
      </formatter>

      <!-- Configure the standard encoder -->
      <encoder name="html"
               class="solr.highlight.HtmlEncoder" />

      <!-- Configure the standard fragListBuilder -->
      <fragListBuilder name="simple"
                       class="solr.highlight.SimpleFragListBuilder"/>

      <!-- Configure the single fragListBuilder -->
      <fragListBuilder name="single"
                       class="solr.highlight.SingleFragListBuilder"/>

      <!-- Configure the weighted fragListBuilder -->
      <fragListBuilder name="weighted"
                       default="true"
                       class="solr.highlight.WeightedFragListBuilder"/>

      <!-- default tag FragmentsBuilder -->
      <fragmentsBuilder name="default"
                        default="true"
                        class="solr.highlight.ScoreOrderFragmentsBuilder">
        <!--
        <lst name="defaults">
          <str name="hl.multiValuedSeparatorChar">/</str>
        </lst>
        -->
      </fragmentsBuilder>

      <!-- multi-colored tag FragmentsBuilder -->
      <fragmentsBuilder name="colored"
                        class="solr.highlight.ScoreOrderFragmentsBuilder">
        <lst name="defaults">
          <str name="hl.tag.pre"><![CDATA[
               <b style="background:yellow">,<b style="background:lawgreen">,
               <b style="background:aquamarine">,<b style="background:magenta">,
               <b style="background:palegreen">,<b style="background:coral">,
               <b style="background:wheat">,<b style="background:khaki">,
               <b style="background:lime">,<b style="background:deepskyblue">]]></str>
          <str name="hl.tag.post"><![CDATA[</b>]]></str>
        </lst>
      </fragmentsBuilder>

      <boundaryScanner name="default"
                       default="true"
                       class="solr.highlight.SimpleBoundaryScanner">
        <lst name="defaults">
          <str name="hl.bs.maxScan">10</str>
          <str name="hl.bs.chars">.,!? &#9;&#10;&#13;</str>
        </lst>
      </boundaryScanner>

      <boundaryScanner name="breakIterator"
                       class="solr.highlight.BreakIteratorBoundaryScanner">
        <lst name="defaults">
          <!-- type should be one of CHARACTER, WORD(default), LINE and SENTENCE -->
          <str name="hl.bs.type">WORD</str>
          <!-- language and country are used when constructing Locale object.  -->
          <!-- And the Locale object will be used when getting instance of BreakIterator -->
          <str name="hl.bs.language">en</str>
          <str name="hl.bs.country">US</str>
        </lst>
      </boundaryScanner>
    </highlighting>
  </searchComponent>

  高亮组件位于查询处理链的下游,因此,高亮组件每次只能对一页搜索结果进行高亮处理。如果页面较大,比如1000,那么每次请求中高亮组件的处理量很大,这会对查询响应时间造成负面影响。

  当需要使用多字段时,例如,数据包含title和body两个字段,并且打算在这两个字段上高亮显示查询词项。在这种情况下,需要设定hl.fl=title,body,这样就能在title和body字段上都进行高亮显示。

  对于hl.fl列表的每个字段,高亮组件将根据hl.snippets参数来决定生成多少个高亮片段,该参数的默认值为1。Solr高亮组件的主要组成如下:

  

  1.文本分析

  在Solr高亮显示结果之前,它需要访问原始文本并将其存储起来。当Solr得到该字段的原始文本之后,它需要使用配置好的索引阶段分析器进行重新分析。对文档的原始文本重新进行分析主要有两个原因。首先,片段中的词项必须能与查询词项相比较。其次,Solr需要知道原始文本中词项的位置偏移量,以便它在片段中高亮显示词项。我们不希望Solr生成的高亮片段漏掉raining的结尾ing。因此,Solr需要知道原始文本中raining开始和结束的位置。位置偏移量很重要,通过它Solr才能知道什么时候该高亮显示一个短语,而不是短语的一部分。词项分析器如下:

  

  2.分段

  分段是选择文本字段中零个或多个子片段进行高亮显示的过程。基于这一点,使用片段表示已排名和格式化的片段,这些片段得分足够高,在结果中得以返回。Solr把文本分隔成片段,每个片段产生一个分数,得分最高的前N个片段作为高亮显示片段被返回,这里的N由参数hl.snippets设定。

  Solr有两个基本方法来实现分段,分别是GapFragmenter和RegexFragmenter。默认方式是GapFragmenter,它基于一个目标长度来选择片段。默认情况下,目标片段长度为100,也可以使用hl.fragsize参数进行修改。RegexFragmenter不会拆分分词来产生固定长度的片段,而GapFragmenter会在分词边界上创建片段。GapFragmenter得名于,它避免了在跨越较大位置间隔上创建片段。例如,在schema.xml文件中字段定义的positionIncrementGap属性上设置多值字段不同值之间的间隔。

  RegexFragmenter通过正则表达式在文本中选择片段。

  3.评分

  分段组件使用了评分组件的子组件为片段评分。默认评分组件的实现方法【QueryScorer】会计算每个分段中出现了多少个查询词项。

  4.编码与格式

  hl.formatter参数指定了一个格式化组件,用来对词项进行高亮显示。默认格式化组件【hl.formatter=simple】将每个词项包含在任意一段文本中。这种方法适用于HTML标签来高亮显示查询词项。默认情况下,simple格式化组件将词项放在<em>标签中,也可以使用hl.simple.pre和hl.simple.post参数覆盖默认值。例如,如果想要使用层叠样式表对高亮词项进行格式化,在查询中添加一下参数即可:

  hl.simple.pre=<span class="foo">&

  hl.simple.post=</span>

  在每个片段传递给格式化组件之前,编码组件需要对特殊字符进行编码。当生成一个HTML高亮片段时,HTML编码器将特殊字符转义为HTML字符实体引用。

五.优化高亮显示结果

  1.与分面一起使用

  

 

  2.高亮显示短语

  在后台,hl.usePhraseHighlighter参数控制这个行为,默认情况下它是启用状态。如果设置hl.usePhraseHighlighter=false,那么Solr可能返回单独高亮显示词项blue或fireball的片段。关键之处在于,Solr在高亮显示查询短语时处理得当。

  3.高亮显示多值字段

  略

  4.高亮参数小结

  

 

  

 

  5.字段级覆写

  很多高亮组件的参数都可以进行字段级覆写。例如,搜索应用有title和body两个字段。标题总是很短,因而只要求产生一个片段;但是若想在较长的body字段上生成三个片段,只需要设置f.body.hl.snippets=3来覆写body字段的默认值1即可。一般情况下,在参数前添加f.fieldname对任意参数应用字段级覆写。

 

posted @ 2020-05-11 10:49  云山之巅  阅读(1421)  评论(0编辑  收藏  举报