分面搜索(faceting)是基于索引词,将搜索结果组织到不同的分类(categories)中。表示为索引词(terms),以及一个数值代表各个词匹配的文档数。
*分面的字段属性:indexed或docValues之一必须为true, 但不是都必须为true. docValues在很多情况下更高效。
- facet
"true" 启用faceting计数。
"false"或blank或missing value, 不启用faceting, 默认值是blank.
- facet.query
可以指定Lucene语法形式的任意query来生成faceting计数。默认,自动检查字段的唯一term并返回计数。
使用facet.query来覆盖默认行为,并精确指定你希望计数的词或正则式。典型的实现中,你可以指定多个facet.query参数。
此参数对于基于数值范围(numeric-range-based)和基于前缀(prefix-based)的分面尤为有用。
对于文本(text)字段, 如果包含分词等处理,处理后的term可能不是你想要的。如果你想要solr对文本字段既分析(搜索),又做分面处理,使用copyField对字段创建两个版本:一个Text和一个String.
- facet.prefix
限制分面term为指定前缀。
按字段指定参数(下同):f.<fieldname>.facet.prefix
- facet.contains
限制分面term为包含指定子串(substring)
- facet.contains.ignoreCase
使用facet.contains时,忽略子串大小写
- facet.sort
count 按计数排序,最高的在前。
index 按字符顺序。
如果facet.limit大于0,默认为count; 否则默认为index
- facet.limit
默认值为100, 负值表示不限.
- facet.offset
默认值0
- facet.mincount
默认值0
- facet.missing
如果设置为true, 会返回匹配查询但没有facet的所有结果的计数。
默认为false.
- facet.method
faceting的算法或方法
enum 枚举字段的所有term,计算匹配term的文档和查询结果文档的交集。推荐用于multi-valued且只有少数值的字段。
fc (field cache)遍历查询结果文档并计数。目前的实现是使用一个非倒排字段缓存,如果字段既非多值也非tokenized.
对于多值字段,使用filterCache的term filters.
fcs 用于single-valued string字段.
默认是fc.
- facet.enum.cache.minDF (Advanced)
仅用于facet.method=enum时,指定filterCache使用的最小文档频率。默认值为0
可以减小内存使用,但增加处理时间。
- Over-Request参数
在Solr分布式查询中,每个分片默认请求 top "10+(1.5 * facet.limit)" 的facets.
facet.overrequest.count 默认10
facet.overrequest.ratio 默认1.5
- facet.threads (Advanced)
facet.threads=N, N个线程被使用。
0或忽略,只有主线程。
负数,最大Integer.MAX_VALUE个线程。
(3) 范围切面(Range Faceting)
你可以在任何的日期和数值字段上使用Range Faceting.
- facet.range
指定字段。
facet.range=price&facet.range=age
facet.range=lastModified_dt
- facet.range.start
f.price.facet.range.start=0.0&f.age.facet.range.start=10
f.lastModified_dt.facet.range.start=NOW/DAY-30DAYS
- facet.range.end
f.price.facet.range.end=1000.0&f.age.facet.range.start=99
f.lastModified_dt.facet.range.end=NOW/DAY+30DAYS
- facet.range.gap
f.price.facet.range.gap=100&f.age.facet.range.gap=10
f.lastModified_dt.facet.range.gap=+1DAY
- facet.range.hardend
true, 最后一个范围以facet.range.end结束。
false, 最后一个范围以gap宽度的上限结束。
- facet.range.include
lower, 默认,[lower, upper)
upper, (lower, upper]
edge, 第一个和最后一个range包含边界
outer, "before"和"after"包含边界
all, 包括lower, upper, edge, outer
可以指定多次。
- facet.range.other
除了匹配的范围之外,还应计数:
before, 第一个range之前的记录
after, 最后一个range之后的记录
between, 在start和end之间的所有记录
none, 不计数
all, 包括:before,after,between
除all之外,可以多次指定,但none会覆盖其他参数。
- facet.range.method
filter, 默认,使用filterCache
dv, 这种方法可利用docValues.
- facet.mincount
小于指定计数的范围不会返回
Pivoting是一个汇总工具,能自动对数据进行排序,计数,求总数和平均。结果通常显示在第二张表中,显示汇总数据。
从另一个角度看,查询产生了一个决策树(Decision Tree), Solr告诉你"对facet A, 约束/计数为X/N, Y/M, 等. 如果约束A为X, 那么B约束计数为S/P, T/Q, 等"
换句话说,如果限定当前的facet结果,那么将提前告诉你字段的下一个facet结果结合。
- facet.pivot
指定pivot字段,多个字段用逗号隔开。
- facet.pivot.mincount
最小数结果数,默认为1.
- Combining Stats Component With Pivots
stats=true
stats.field={!tag=piv1,piv2 min=true max=true}price # 统计最大值,最小值
stats.field={!tag=piv2 mean=true}popularity # 平均值
facet=true
facet.pivot={!stats=piv1}cat,inStock
facet.pivot={!stats=piv2}manu,inStock
- Combining Facet Queries And Facet Ranges With Pivot Facets
facet=true
facet.query={!tag=q1}manufacturedate_dt:[2006-01-01T00:00:00Z TO NOW]
facet.query={!tag=q1}price:[0 TO 100]
facet.pivot={!query=q1}cat,inStock
facet=true
facet.range={!tag=r1}manufacturedate_dt
facet.range.start=2006-01-01T00:00:00Z
facet.range.end=NOW/YEAR
facet.range.gap=+1YEAR
facet.pivot={!range=r1}cat,inStock
- facet.interval
指定字段,可多次指定。
facet.interval=price&facet.interval=size
- facet.interval.set
指定字段的区间值,可多次指定。
f.price.facet.interval.set=[0,10]&f.price.facet.interval.set=(10,100]
Interval语法:
例
(1,10]
[1,10)
[1,10]
(*,5]
(*,*)
[Abc, Bbc]
改变输出的key名称:
&facet.interval={!key=popularity}some_field
&facet.interval.set={!key=bad}[0,5]
&facet.interval.set={!key=good}[5,*]
&facet=true
下面的查询,faceting时除doctype:pdf之外的结果全部是0:
q=mainquery&fq=status:public&fq=doctype:pdf&facet=true&facet.field=doctype
下面的查询,Faceting时排除(不考虑)filterQuery:
q=mainquery&fq=status:public&fq={!tag=dt}doctype:pdf&facet=true&facet.field={!ex=dt}doctype
Heatmap Faceting (Spatial)
*分面的字段属性:indexed或docValues之一必须为true, 但不是都必须为true. docValues在很多情况下更高效。
(1) 通用参数
- facet
"true" 启用faceting计数。
"false"或blank或missing value, 不启用faceting, 默认值是blank.
- facet.query
可以指定Lucene语法形式的任意query来生成faceting计数。默认,自动检查字段的唯一term并返回计数。
使用facet.query来覆盖默认行为,并精确指定你希望计数的词或正则式。典型的实现中,你可以指定多个facet.query参数。
此参数对于基于数值范围(numeric-range-based)和基于前缀(prefix-based)的分面尤为有用。
(2) 字段-值Faceting参数
有若干参数可以用来触发在指定字段的term上进行faceting.对于文本(text)字段, 如果包含分词等处理,处理后的term可能不是你想要的。如果你想要solr对文本字段既分析(搜索),又做分面处理,使用copyField对字段创建两个版本:一个Text和一个String.
- facet.field
指定分面字段,可多次指定。至少指定一个,其他参数才有效果。- facet.prefix
限制分面term为指定前缀。
按字段指定参数(下同):f.<fieldname>.facet.prefix
- facet.contains
限制分面term为包含指定子串(substring)
- facet.contains.ignoreCase
使用facet.contains时,忽略子串大小写
- facet.sort
count 按计数排序,最高的在前。
index 按字符顺序。
如果facet.limit大于0,默认为count; 否则默认为index
- facet.limit
默认值为100, 负值表示不限.
- facet.offset
默认值0
- facet.mincount
默认值0
- facet.missing
如果设置为true, 会返回匹配查询但没有facet的所有结果的计数。
默认为false.
- facet.method
faceting的算法或方法
enum 枚举字段的所有term,计算匹配term的文档和查询结果文档的交集。推荐用于multi-valued且只有少数值的字段。
fc (field cache)遍历查询结果文档并计数。目前的实现是使用一个非倒排字段缓存,如果字段既非多值也非tokenized.
对于多值字段,使用filterCache的term filters.
fcs 用于single-valued string字段.
默认是fc.
- facet.enum.cache.minDF (Advanced)
仅用于facet.method=enum时,指定filterCache使用的最小文档频率。默认值为0
可以减小内存使用,但增加处理时间。
- Over-Request参数
在Solr分布式查询中,每个分片默认请求 top "10+(1.5 * facet.limit)" 的facets.
facet.overrequest.count 默认10
facet.overrequest.ratio 默认1.5
- facet.threads (Advanced)
facet.threads=N, N个线程被使用。
0或忽略,只有主线程。
负数,最大Integer.MAX_VALUE个线程。
(3) 范围切面(Range Faceting)
你可以在任何的日期和数值字段上使用Range Faceting.
- facet.range
指定字段。
facet.range=price&facet.range=age
facet.range=lastModified_dt
- facet.range.start
f.price.facet.range.start=0.0&f.age.facet.range.start=10
f.lastModified_dt.facet.range.start=NOW/DAY-30DAYS
- facet.range.end
f.price.facet.range.end=1000.0&f.age.facet.range.start=99
f.lastModified_dt.facet.range.end=NOW/DAY+30DAYS
- facet.range.gap
f.price.facet.range.gap=100&f.age.facet.range.gap=10
f.lastModified_dt.facet.range.gap=+1DAY
- facet.range.hardend
true, 最后一个范围以facet.range.end结束。
false, 最后一个范围以gap宽度的上限结束。
- facet.range.include
lower, 默认,[lower, upper)
upper, (lower, upper]
edge, 第一个和最后一个range包含边界
outer, "before"和"after"包含边界
all, 包括lower, upper, edge, outer
可以指定多次。
- facet.range.other
除了匹配的范围之外,还应计数:
before, 第一个range之前的记录
after, 最后一个range之后的记录
between, 在start和end之间的所有记录
none, 不计数
all, 包括:before,after,between
除all之外,可以多次指定,但none会覆盖其他参数。
- facet.range.method
filter, 默认,使用filterCache
dv, 这种方法可利用docValues.
- facet.mincount
小于指定计数的范围不会返回
(4) Date切面参数
弃用(deprecated), 参见range facet(5) 支点(决策树)分面 Pivot (Decision Tree) Faceting
Pivoting是一个汇总工具,能自动对数据进行排序,计数,求总数和平均。结果通常显示在第二张表中,显示汇总数据。
从另一个角度看,查询产生了一个决策树(Decision Tree), Solr告诉你"对facet A, 约束/计数为X/N, Y/M, 等. 如果约束A为X, 那么B约束计数为S/P, T/Q, 等"
换句话说,如果限定当前的facet结果,那么将提前告诉你字段的下一个facet结果结合。
- facet.pivot
指定pivot字段,多个字段用逗号隔开。
- facet.pivot.mincount
最小数结果数,默认为1.
- Combining Stats Component With Pivots
stats=true
stats.field={!tag=piv1,piv2 min=true max=true}price # 统计最大值,最小值
stats.field={!tag=piv2 mean=true}popularity # 平均值
facet=true
facet.pivot={!stats=piv1}cat,inStock
facet.pivot={!stats=piv2}manu,inStock
- Combining Facet Queries And Facet Ranges With Pivot Facets
facet=true
facet.query={!tag=q1}manufacturedate_dt:[2006-01-01T00:00:00Z TO NOW]
facet.query={!tag=q1}price:[0 TO 100]
facet.pivot={!query=q1}cat,inStock
facet=true
facet.range={!tag=r1}manufacturedate_dt
facet.range.start=2006-01-01T00:00:00Z
facet.range.end=NOW/YEAR
facet.range.gap=+1YEAR
facet.pivot={!range=r1}cat,inStock
(6) 区间分面(Interval Faceting)
Interval Faceting听起来像范围分面(range faceting), 但此功能更接近使用了范围查询的分面查询。- facet.interval
指定字段,可多次指定。
facet.interval=price&facet.interval=size
- facet.interval.set
指定字段的区间值,可多次指定。
f.price.facet.interval.set=[0,10]&f.price.facet.interval.set=(10,100]
Interval语法:
例
(1,10]
[1,10)
[1,10]
(*,5]
(*,*)
[Abc, Bbc]
改变输出的key名称:
&facet.interval={!key=popularity}some_field
&facet.interval.set={!key=bad}[0,5]
&facet.interval.set={!key=good}[5,*]
&facet=true
(7) Faceting的本地(定制)参数
- Tagging和Excluding过滤器下面的查询,faceting时除doctype:pdf之外的结果全部是0:
q=mainquery&fq=status:public&fq=doctype:pdf&facet=true&facet.field=doctype
下面的查询,Faceting时排除(不考虑)filterQuery:
q=mainquery&fq=status:public&fq={!tag=dt}doctype:pdf&facet=true&facet.field={!ex=dt}doctype
(8) Related Topics
SimpleFacetParametersHeatmap Faceting (Spatial)
(9) BlockJoin Faceting
如果一个父文档有几个子文档,它们对于Faceting只需要计数1次,通过父文档聚合子文档计数是一个通用的需求。BlockJoinFacetComponent和BlockJoinDocSetFacetComponent这两个性能有所差异的搜索组件提供了此功能。