分组统计之facet

背景: 在shop商城的商品列表页,我们都可以看到商品按分类,品牌,价格的分类显示,如图(1),这些我们可以使用solr中的facet功能实现。

                                                                      图(1)

1. Facet简介

          Facet是solr的高级搜索功能之一,可以给用户提供更友好的搜索体验。在搜索关键字的同时,能够按照Facet的字段进行分组并统计,类似数据库的count(*) group by 功能。

2. Facet字段的要求

       Facet的字段必须被索引。一般来说该字段无需分词,无需存储。

       无需分词是因为该字段的值代表了一个整体概念,如电脑的品牌”联想”代表了一个整 体概念,如果拆成”联”、”想”两个字都不具有实际意义。另外该字段的值无需进行大小写转换等处理,保持其原貌即可。

       无需存储是因为一般而言用户所关心的并不是该字段的具体值,而是作为对查询结果进行分组的一种手段,用户一般会沿着这个分组进一步深入搜索。

3. 特殊情况

       对于一般查询而言,分词和存储都是必要的.比如CPU类型”Intel 酷睿2双核 P7570”, 拆分成”Intel”、”酷睿”、”P7570”这样一些关键字并分别索引,可能提供更好的搜索体验。但是如果将CPU作为Facet字段,最好不进行分词。这样就造成了矛盾,解决方法为:将CPU字段设置为不分词不存储,然后建立另外一个字段为它的COPY,对这个COPY的字段进行分词和存储。

4.facet组件

 Solr的默认requestHandler已经包含了Facet组件(solr.FacetComponent),所以不需要我们在配置。如果自定义requestHandler或者对默认的requestHandler自定义组件列表,那么需要将Facet加入到组件列表中去。

5.facet用法

       facet.field 指定要分类的字段。

       facet=on 或 facet=true 表示功能开启。

       facet.prefix  表示字段前缀,比如facet.field=cpu&facet.prefix=Intel,那么对cpu字段进行Facet查询,返回的cpu都是以Intel开头的,AMD开头的cpu型号将不会被统计在内。

       facet.limit  表示返回的记录数,默认值为100.如果此值为负数,表示不限制。

       facet.offict  表示返回结果集的偏移量,默认为0,它与facet.limit配合使用可以达到分页的效果。

       facet.mincount  限制了Facet字段值的最小count,默认为0。合理设置该参数可以将用户的关注点集中在少数比较热门的领域。

       facet.missing   默认为””,如果设置为true或者on,那么将统计那些该Facet字段值为null的记录。

       facet.method   取值为enum或fc,默认为fc。该字段表示了两种Facet的算法,与执行效率相关.

              enum适用于字段值比较少的情况,比如字段类型为布尔型,或者字段表示中国的所有省份。Solr会遍历该字段的所有取值,并从filterCache里为每个值分配一个filter(这里要求solrconfig.xml里对filterCache的设置足够大)。然后计算每个filter与主查询的交集。

              fc(表示Field Cache)适用于字段取值比较多,但在每个文档里出现次数比较少的情况。Solr会遍历所有的文档,在每个文档内搜索Cache内的值,如果找到就将Cache内该值的count加1。

       facet.enum.cache.minDf    当facet.method=enum时,此参数其作用:minDf表示minimum document frequency,也就是文档内出现某个关键字的最少次数,该参数默认值为0,设置该参数可以减少filterCache的内存消耗,但会增加总的查询时间(计算交集的时间增加了)。如果设置该值的话,官方文档建议优先尝试25-50内的值。

       facet.query可以任意定义查询。

6. facet查询

Facet字段通过在请求中加入facet.field参数加以声明,如果需要对多个字段进行Facet查询,那么将该参数声明多次.例如:

http://127.0.01:8080/solr/core_shop_product/select?q=*%3A*&wt=json&indent=true&facet=true&facet.field=category_id&facet.field=brand_id

访问以上链接会出现如图(2)和图(3)的效果:

category_id的统计结果:

                                                                                     图(2)

                                                                                   图(3)

 

7. tag操作符和ex操作符

     当查询使用filter query的时候,如果filter query的字段正好是Facet字段,那么查询结果往往被限制在某一个值内。

    例:

        &fq=category_id:4348

        &facet=on

        &facet.field=category_id

       链接为:

        http://127.0.01:8080/solr/core_shop_product/select?q=category_id%3A4348&wt=json&indent=true&facet=true&facet.field=category_id&facet.field=brand_id

    查询结果如图(4):

                                                                            图(4)

       可以看到,分类id(category_id)为4348的产品共有2件,其它分类的产品的数目都是0,这是因为在filter里已经限制了category_id:434。这样,查询结果中除了category_id:434的这一项之外,其它项目没有实际的意义。有些时候用户希望把结果限制在某一范围内,又希望查看该范围外的概况。比如上述情况,既要把查询结果限制在分类4348下,又想查看一下其它分类下有多少产品。这个时候需要用到tag和ex操作符。tag就是把一个filter标记起来,ex(exclude)是在Facet的时候把标记过的filter排除在外。

例:

     &fq={!tag=aa}category_id:4348

    &facet=on

    &facet.field={!ex=aa}category_id

链接为:

http://127.0.01:8080/solr/core_shop_product/select?q={!tag=aa}category_id%3A4348&wt=json&indent=true&facet=true&facet.field={!ex=aa}category_id&facet.field=brand_id

查询结果如图(5):

                                                                         图(5)

这样就能看到其他分类下的商品数量。

8. facet在solrj中的使用如图(6):

                                                                      图(6)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值