初识solr facet(一)

内容纲要

Facet概述

Facet(直译为分面,实践来看可以叫做聚合)是由facet component支持的,将查询结果根据指定条件进行动态聚合,获得各类目信息的功能。

使用场景

最常见的一个例子是购物导航栏,如下图。在搜索“电脑”一词时,我们除了获得搜索结果,还会看到最上方的导航栏,它告诉我们关键词带有“电脑”的商品,分了几大类,每一类下面各有多少商品。购物导航栏
这就是facet功能的一个最基础的应用。这个好处是能引导用户逐步缩小搜索结果范围,最终找到自己想要的结果。

另一个场景是在筛选栏中替代传统的静态列表。如下图,选择行政区后,会下拉展开行政区下面的商圈。但与传统下拉列表不同的是,这里不会展示该区域下的所有商圈,只会展示有结果的商圈,避免用户的无效点击。这也是facet的功劳。
筛选栏

快速上手

想要在solr中使用这一功能,只需要简单的三步:

  1. 确认facetComponent加入请求处理链(SearchHandler默认有)
  2. 把要聚合的字段设置为可索引,或为此字段构建docValues正向索引
  3. 请求时增加facet=on&facet.field=field参数

将facetComponent加入请求处理链

Facet功能由facet组件提供支持,我们要确保在进行请求处理时能够调用这个组件。我们在solrconfig.xml中看到这样一段话:

<!-- Search Components

       Search components are registered to SolrCore and used by 
       instances of SearchHandler (which can access them by name)

       By default, the following components are available:

       <searchComponent name="query"     class="solr.QueryComponent" />
       <searchComponent name="facet"     class="solr.FacetComponent" />
       <searchComponent name="highlight" class="solr.HighlightComponent" />
       <searchComponent name="stats"     class="solr.StatsComponent" />
       <searchComponent name="debug"     class="solr.DebugComponent" />

       Default configuration in a requestHandler would look like:

       <arr name="components">
         <str>query</str>
         <str>facet</str>
         <str>mlt</str>
         <str>highlight</str>
         <str>stats</str>
         <str>debug</str>
       </arr>
-->

可见只要我们使用默认的searchHandler,而且不对component进行个性化设定,那么请求会被query、facet、mlt、highlight、stats、debug组件逐步处理。
如果使用自定义的Handler,或者覆写了componet列表,就需要注意加入facet component来支持聚合操作,否则该功能不生效。

字段索引

在前面筛选栏的例子,我们要知道哪些商圈有这个商品,假设商品的“商圈”字段名为commertial_district,那么需要indexd="true"或者docValues="true"
如果对未索引的字段进行facet,则获得结果为空,但也不会报错

小试牛刀

http://localhost:7070/solr/test/search?q=*:*&rows=0&facet=on&facet.field=prescription_type

这是最简单的使用,按指定字段值进行分组统计。可以看到除了docs之外,还返回了facet_count,所有和facet相关的结果都在这个key下。
facet基础使用

Facet基础

常用参数

根据经验,以下参数能满足最基础的按值计数查询。
详情查询 Solr Ref Guide 6.6 Facet

参数 功能 默认值
facet.field 指定需要分面的字段
facet.limit 限制facet结果数目 100
facet.sort 排序方式,可以是count(个数从高到低)或index(字典顺序) count
facet.mincount facet 字段某值的计数小于此值,则不返回此值 0
facet.method 指定使用的算法enum/fc/fcs/uif fc
facet.prefix 指定字符串开头的词项来限制分面值,常用于自动补全功能
facet.missing 是否返回不含值的文档计数 False

facet query/range/interval

除了最常用的facet.field,在实际中还可能用到facet.queryfacet.rangefacet.interval

facet.query

  • 使用facet.query灵活指定查询,统计符合指定查询的doc数。
  • 可在同一查询中指定不同类型的facet query类型,如下图,一个为范围查询,一个为枚举查询。
  • docs中的文档数仅受fq参数影响,facet.query不影响这里。
    facet.query1

    facet.range

    如果说facet.query是最灵活的用法,那么facet.range则是为间距(gap)固定的范围查询量身定制的方法。下图中一目了然:
    facet.range

    facet.interval

    facet.range的缺憾是每个组的范围是一样的,不太灵活,facet.interval则弥补了这个不足。

  • 使用小括号和中括号控制开闭区间

facet.interval

小Tips

  • 对多值字段进行按值计数时,同一个doc中的不同值会分别计数一次,facet结果中各项之和可能会大于总doc数,这是正常的;
  • 对分词类型字段进行按值统计时,会根据分词后的结果词来计算:

在这里插入图片描述

小结

facet只是查询中的一个环节,可讲的内容却不少,随便一写,文章也不短了。
作为基础,这一篇差不多够了,请期待下集!

参考

  1. 《solr in action》
  2. facet: https://lucene.apache.org/solr/guide/6_6/faceting.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注