solr 之 facet 查询

1. 例子:

http://172.16.132.159:6602/sse/vod_media/select?q=title%3A%E8%8B%B1%E9%9B%84&wt=json&facet=true&facet.field=category_id

 

  • facet_counts: 
     
    {
    • facet_queries: { },
    • facet_fields: 
       
      {
      • category_id: 
         
        [
        • "1100",
        • 18,
        • "1001",
        • 10,
        • "1011",
        • 9,
        • "1005",
        • 8,
        • "1012",
        • 7,
        • "1004",
        • 6,
        • "1003",
        • 5,
        • "1007",
        • 3,
        • "1017",
        • 3,
        • "1010",
        • 2,
        • "1002",
        • 0,
        • "1006",
        • 0,
        • "1008",
        • 0,
        • "1014",
        • 0,
        • "1018",
        • 0
        ]
      },
    • facet_dates: { },
    • facet_ranges: { }
    }

}

 

solr facet 是solr搜索的一大特色,facet不好翻译,有说是垂直搜索,有说是分片搜索,但都不是很好,还是懒得翻译了,就叫facet ,具体功能看下面的例子意会吧。

 

比如你上淘宝,输入“笔记本”进行搜索,就会出现品牌分类,价格范围等分类,这个就叫facet了。这个例子也许好不是那么准确的描述facet,不过基本上就是这个意思。对输入关键字后搜索出来的结果再进行分类。

 


solr将以导航为目的的查询结果称为facet. 它并不会修改查询结果信息, 只是在查询结果上根据分类添加了count信息, 然后用户根据count信息做进一步的查询, 比如淘宝的查询列表中, 上面会表示不同的类目相关查询结果的数量. 

比如搜索数码相机, 在搜索结果栏会根据厂商, 分辨率等维度列出, 这里厂商, 分辨率就是一个个facet. 

然后在厂商下面会有nikon, canon, sony等品牌, 这个叫约束(constraints) 

接下来是根据选择, 列出当前的导航路径, 这个叫面包屑(breadcrumb). 

solr有几种facet: 
普通facet, 比如从厂商品牌的维度建立fact 
查询facet, 比如根据价格查询时, 将根据价格, 设置多个区间, 比如0-10, 10-20, 20-30等 
日期facet, 也是一种特殊的范围查询, 比如按照月份进行facet. 

facet的主要好处就是可以任意对搜索条件进行组合, 避免无效搜索, 改善搜索体验. 

facet都是在查询时通过参数指定. 比如 
在http api中这样写: 

引用
"&facet=true&facet.field=manu"


java代码这样写: 

Java代码  收藏代码
  1. new SolrQuery("*:*").setFacet(true).addFacetField("manu");  



而xml返回的结果为这样: 

Xml代码  收藏代码
  1. <lst name="facet_fields">  
  2.             <lst name="manu">  
  3.                <int name="Canon USA">17</int>  
  4.                <int name="Olympus">12</int>  
  5.                <int name="Sony">12</int>  
  6.                <int name="Panasonic">9</int>  
  7.                <int name="Nikon">4</int>  
  8.             </lst>  
  9. </lst>  



通过java代码可以这样获取facet结果: 

Java代码  收藏代码
  1. List<FacetField> facetFields = queryResponse.getFacetFields();  



在已有的查询基础上增加facet query, 可以这样写: 

Java代码  收藏代码
  1. solrQuery.addFacetQuery("quality:[* TO 10]")  



比如对价格按照指定的区间进行facet, 可以这样加上facet后缀: 

引用
&facet=true&facet.query=price:[* TO 100] 
&facet.query=price:[100 TO 200];&facet.query=[price:200 TO 300] 
&facet.query=price:[300 TO 400];&facet.query=[price:400 TO 500] 
&facet.query=price:[500 TO *]



如果要对价格在400到500期间的产品做进一步的搜索, 那么可以这样写(使用了solr的过滤查询): 

引用
http://localhost:8983/solr/select?q=camera &facet=on&facet.field=manu&facet.field=camera_type &fq=price:[400 to 500]



注意这里的facet field不再包含price了 

如果这里对类型做进一步的查询, 那么query语句可以这样写: 

引用
http://localhost:8983/solr/select?q=camera &facet=on&facet.field=manu &fq=price:[400 to 500] &fq=camera_type:SLR 



facet的使用场景: 
1.类目导航 
2.自动提示, 需要借助一个支持多值的tag field. 
3.热门关键词排行, 也需要借助一个tag field 

 

三、facet 参数

facet的参数见solr官方wiki  http://wiki.apache.org/solr/SimpleFacetParameters

 

说明:

搜索结果按照Facet的字段分组并统计

 

facet 参数字段要求

字段必须被索引

 

#.field Facet

facet=on 或 facet=true

 

1.facet.field  

分组的字段

2.facet.prefix 

表示Facet字段前缀

3.facet.limit 

Facet字段返回条数

4.facet.offict 

开始条数,偏移量,它与facet.limit配合使用可以达到分页的效果

5.facet.mincount 

Facet字段最小count,默认为0

6.facet.missing 

如果为on或true,那么将统计那些Facet字段值为null的记录

7.facet.method 

取值为enum或fc,默认为fc, fc表示Field Cache

8.facet.enum.cache.minDf 

当facet.method=enum时,参数起作用,文档内出现某个关键字的最少次数

 

例:

&facet=on

&facet.field=city_id

&facet.field=address

 

http://localhost:8983/solr/select/?q=*:*&indent=on&facet=on&facet.field=unit_price&facet.field=developer_id

 

返回结果facet_counts:

 

Xml代码  收藏代码
  1. <lst name="facet_counts">  
  2. <lst name="facet_queries"/>  
  3. <lst name="facet_fields">  
  4.     <lst name="unit_price">  
  5.         <int name="9100.0">2</int>  
  6.         <int name="1100.0">1</int>  
  7.     </lst>  
  8.     <lst name="developer_id">  
  9.         <int name="101">2</int>  
  10.         <int name="100">1</int>  
  11.     </lst>  
  12. </lst>  
  13. <lst name="facet_dates"/>  
  14. </lst>  

 

#.Date Facet

日期类型的字段

 

1.facet.date 

表示需要Data Facet的字段名

2.facet.date.start

起始时间.时间一般格式为"1995-12-31T12:59:59Z"

另外可以使用"NOW","YEAR","MONTH"等

3.facet.date.end

结束时间

4.facet.date.gap

时间间隔

5.facet.date.hardend

true|false 

6.facet.date.other

before|after|between|none|all 默认为none

before会对start之前的值做统计

after会对end之后的值做统计

between会对start至end之间的值做统计,如果hardend为true的话,那么改值就是各个时间段统计值的和

none 表示该项禁用

all 表示before,after,all都会统计

 

例:

$facet=on

&facet.date=date

&facet.date.start=2009-1-1T0:0:0Z

&facet.date.end=2010-1-1T0:0:0Z

&facet.date.gap=;1MONTH

&facet.date.other=all

 

7.facet.date.include

lower|upper|edge|outer|all

 

 

#.Facet Query

facet.query 可以对任意的字段进行筛选

 

例:

&facet=on

&facet.query=date:[2009-1-1T0:0:0Z TO 2010-1-1T0:0:0Z]

posted @ 2014-12-15 17:00  清晰-模块-组合-优化  阅读(413)  评论(0)    收藏  举报