1. facet介绍
solr将以导航为目的的查询结果称为facet.它并不会修改查询结果信息,只是在查询结果上根据分类添加了count信息, 然后用户根据count信息做进一步的查询,比如淘宝的查询列表中,上面会表示不同的类目相关查询结果的数量.
比如搜索数码相机,在搜索结果栏会根据厂商,分辨率等维度列出,这里厂商,分辨率就是一个个facet.
然后在厂商下面会有nikon,canon,sony等品牌, 这个叫约束(constraints)
接下来是根据选择,列出当前的导航路径,这个叫面包屑(breadcrumb).
solr有几种facet:
(1)普通facet,比如从厂商品牌的维度建立fact
(2) 查询facet,比如根据价格查询时, 将根据价格, 设置多个区间, 比如0-10, 10-20, 20-30等
(3)日期facet,也是一种特殊的范围查询,比如按照月份进行facet.
facet的主要好处就是可以任意对搜索条件进行组合,避免无效搜索,改善搜索体验.
2. facet查询
进行Facet查询需要在请求参数中加入”facet=on”或者”facet=true”只有这样Facet组件才起作用.
(1) Field Facet
Facet字段通过在请求中加入”facet.field”参数加以声明,如果需要对多个字段进行Facet查询,那么将该参数声明多次.比如:
http://localhost:8080/solr/select?q=*:*&facet=on&facet.field=name&facet.field=sex
java代码可以这样写:new SolrQuery("*:*").setFacet(true).addFacetField("name").addFacetField("sex");
通过java代码可以这样获取facet结果:
List<FacetField> facetFields = queryResponse.getFacetFields();
查询返回结果如下
注意:name最好不要使用中文名字,否者分词器会把中文名字进行拆分,出现如下结果(让大家见笑了,其实可以使用中文,之前只是我没安装中文分词器,所以才出现如下情况)
如上例中还需添加age字段查询,则再加上&facet.field=age;如还指定了age范围20到30岁,则写成&fq=age:[20 TO 30]
3. facet参数
facet的参数见solr官方wiki http://wiki.apache.org/solr/SimpleFacetParameters
说明:搜索结果按照Facet的字段分组并统计
facet 参数字段要求:字段必须被索引
(1)field Facet说明如下
Facet.field:分组的字段
facet.prefix:表示Facet字段前缀
facet.limit:Facet字段返回条数
facet.offict:开始条数,偏移量,它与facet.limit配合使用可以达到分页的效果
facet.mincount:Facet字段最小count,默认为0
facet.missing:如果为on或true,那么将统计那些Facet字段值为null的记录
facet.method:取值为enum或fc,默认为fc, fc表示Field Cache
facet.enum.cache.minDf:当facet.method=enum时,参数起作用,文档内出现某个关键字的最少次数
例:
&facet=on&facet.field=city_id&facet.field=address
(2)Date Facet说明如下
facet.date:表示需要Data Facet的字段名
facet.date.start:起始时间.时间一般格式为"1995-12-31T12:59:59Z",另外可以使用"NOW","YEAR","MONTH"等
facet.date.end:结束时间
facet.date.gap:时间间隔
facet.date.hardend:true|false
facet.date.include:lower|upper|edge|outer|all
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
(3)Facet Query说明如下
facet.query:可以对任意的字段进行筛选
例:
&facet=on&facet.query=date:[2009-1-1T0:0:0ZTO 2010-1-1T0:0:0Z]
(4)Facet Range说明如下
注意:range范围是左闭右开[start, end),如下
http://localhost:8080/solr/select?&facet=true&facet.range=price&facet.range.start=5000&facet.range.end=8000&facet.range.gap=1000
输出结果如下
"facet_counts":{
"facet_ranges":{
"price":{
"counts”:[
"5000.0”,5,
"6000.0”,2,
"7000.0”,3,],
"gap":1000.0,
"start":5000.0,
"end":8000.0}}}}
(5)Facet Pivot说明如下
这个是Solr 4.0的新特性,pivot和facet一样难理解,还是用例子来讲吧。
语法:facet.pivot=field1,field2,field3...
例如: facet.pivot=comment_user,grade
| #docs | #docs grade:好 | #docs grade:中 | #docs grade:差 |
comment_user:1 | 10 | 8 | 1 | 1 |
comment_user:2 | 20 | 18 | 2 | 0 |
comment_user:3 | 15 | 12 | 2 | 1 |
comment_user:4 | 18 | 15 | 2 | 1 |
输出结果如下
"facet_counts":{
"facet_pivot":{
"comment_user, grade ":[{
"field":"comment_user",
"value":"1",
"count":10,
"pivot":[{
"field":"grade",
"value":"好",
"count":8}, {
"field":"grade",
"value":"中",
"count":1}, {
"field":"grade",
"value":"差",
"count":1}]
},{
"field":" comment_user ",
"value":"2",
"count":20,
"pivot":[{……
没有pivot机制的话,要做到上面那点可能需要多次查询:
http://...q=comment&fq=grade:好&facet=true&facet.field=comment_user
http://...q=comment&fq=grade:中&facet=true&facet.field=comment_user
http://...q=comment&fq=grade:差&facet=true&facet.field=comment_use