您可以使用两种方法来过滤搜索结果:
- 使用带有
filter
子句的布尔查询。搜索请求将boolean_filter
应用于搜索匹配和 [聚合]。 - 使用搜索API的
post_filter
参数。搜索请求仅将post_filter
应用于搜索匹配,而不应用于汇总。您可以使用后置过滤器根据更广泛的结果集计算聚合,然后进一步缩小结果范围。
您还可以在post_filter
之后重新筛选结果,以提高相关性和重新排序结果。
Post filter
当您使用post_filter
参数过滤搜索结果时,将在计算汇总后过滤搜索结果。 后置过滤器对聚合结果没有影响。
例如,您出售的衬衫具有以下属性:
PUT /shirts
{
"mappings": {
"properties": {
"brand": { "type": "keyword"},
"color": { "type": "keyword"},
"model": { "type": "keyword"}
}
}
}
PUT /shirts/_doc/1?refresh
{
"brand": "gucci",
"color": "red",
"model": "slim"
}
假设用户指定了两个过滤器:
颜色:red和品牌:gucci。 您只想在搜索结果中向他们显示Gucci制造的红色衬衫。 通常,您可以使用布尔查询进行此操作:
GET /shirts/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "color": "red" }},
{ "term": { "brand": "gucci" }}
]
}
}
}
但是,您还想显示其他选项让用户可以选择。 也许您有一个“款式”字段,该字段将允许用户将其搜索结果限制为red-gucci“ T恤衫”或“礼服衬衫”。
可以使用[terms聚合]完成,额外返回red-gucci衣服的款式:
GET /shirts/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "color": "red" }},
{ "term": { "brand": "gucci" }}
]
}
},
"aggs": {
"models": {
"terms": { "field": "model" }
}
}
}
但也许您还想告诉用户有多少种Gucci其他颜色的衬衫可供选择。 如果仅在color字段上添加term聚合,则只会返回red,因为查询仅的是红色的Gucci衬衫。
相反,您希望在聚合过程中返回包括所有颜色的衬衫,然后在搜索结果中仅对“颜色”进行过滤。 通过post_filter
实现目的:
GET /shirts/_search
{
"query": {
"bool": {
"filter": {
"term": { "brand": "gucci" }
}
}
},
"aggs": {
"colors": {
"terms": { "field": "color" }
},
"color_red": {
"filter": {
"term": { "color": "red" }
},
"aggs": {
"models": {
"terms": { "field": "model" }
}
}
}
},
"post_filter": {
"term": { "color": "red" }
}
}
主查询所有的gucci衬衫,不管是什么颜色。
聚合colors
返回gucci衬衫的所有颜色分类
聚合color_red
将限制返回款式只能是红色的gucci衬衫
最后,post_filter
把搜索返回的结果过滤删除红色以外的颜色
重新筛选过滤后的结果
通过使用辅助算法,而不是对索引中的所有文档使用算法,仅通过排序由query和 post_filter阶段返回的最前面(例如100-500个)文档,重新排序可以帮助提高准确性 。
在每个分片上执行一个重新打分请求,然后返回其结果,该结果将由处理整个搜索请求的节点进行排序。
当前,rescore API目前只有一种实现:查询rescorer,该查询可以重新调整评分
如果为rescore
查询提供了显式排序(降序为_score
除外),则会引发错误。
另外在分也是请不要修改from
,因为这可能会更改匹配结果,从而导致用户的浏览页面发生混乱。
Query rescorer
查询重新评分仅对[query]和[post_filter]阶段返回的前K个结果执行第二次查询。 每个分片上要检查的文档数量可以由window_size
参数控制,该参数默认为10。
默认情况下,原始查询和重新评分查询的评分会线性组合,以生成每个文档的最终“ _score”。 原始查询和重新评分查询的相对重要性可以分别通过query_weight
和rescore_query_weight
进行控制。 两者均默认为1。
举例:
POST /_search
{
"query" : {
"match" : {
"message" : {
"operator" : "or",
"query" : "the quick brown"
}
}
},
"rescore" : {
"window_size" : 50,
"query" : {
"rescore_query" : {
"match_phrase" : {
"message" : {
"query" : "the quick brown",
"slop" : 2
}
}
},
"query_weight" : 0.7,
"rescore_query_weight" : 1.2
}
}
}
分数的组合方式可以通过score_mode
控制:
Score Mode | Description |
| 将原始分数和重新评分查询分数相加。默认是相加的 |
| 将原始分数和重新评分查询分数相乘。 |
| 取原始分数和重新评分查询分数的平均数。 |
| 取得原始分数和重新评分查询分数的最大值。 |
| 取原始分数和重新评分查询分数的最小值。 |
多个重新评分
也可以依次执行多个重新评分:
POST /_search
{
"query" : {
"match" : {
"message" : {
"operator" : "or",
"query" : "the quick brown"
}
}
},
"rescore" : [ {
"window_size" : 100,
"query" : {
"rescore_query" : {
"match_phrase" : {
"message" : {
"query" : "the quick brown",
"slop" : 2
}
}
},
"query_weight" : 0.7,
"rescore_query_weight" : 1.2
}
}, {
"window_size" : 10,
"query" : {
"score_mode": "multiply",
"rescore_query" : {
"function_score" : {
"script_score": {
"script": {
"source": "Math.log10(doc.count.value + 2)"
}
}
}
}
}
} ]
}
先获取第一次的查询结果,然后第二次获取第一次的查询结果,依此类推。第二次重新评分将基于第一次结果重新评分完成的排序,因此可以在第一次重新评分上使用较多的数据来查询将结果缩小范围以进行第二次重新评分。