Elasticsearch 过滤搜索结果与重评分机制详解

Elasticsearch 过滤搜索结果与重评分机制详解

过滤搜索结果的两种方法

在 Elasticsearch 中,我们可以使用两种主要方法来过滤搜索结果:

1. 使用布尔查询的 filter 子句

这种方法会将过滤条件同时应用于搜索结果和聚合结果。例如:

GET /products/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "category": "electronics" }},
        { "range": { "price": { "gte": 100, "lte": 500 }}}
      ]
    }
  }
}

2. 使用 post_filter 参数

这种方法的特点是聚合计算会在过滤之前进行,过滤只影响最终的搜索结果,不影响聚合结果。这在电商网站的分面导航(faceted navigation)场景中特别有用。

post_filter 的实际应用

让我们通过一个服装电商的案例来理解 post_filter 的实际价值。假设我们有以下数据结构:

PUT /shirts
{
  "mappings": {
    "properties": {
      "brand": { "type": "keyword"},
      "color": { "type": "keyword"},
      "model": { "type": "keyword"}
    }
  }
}

场景需求

用户想查看"红色Gucci衬衫",但同时我们还想展示:

  1. Gucci品牌的其他颜色选择
  2. 红色Gucci衬衫的不同款式

解决方案对比

传统布尔查询方式

GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "color": "red" }},
        { "term": { "brand": "gucci" }}
      ]
    }
  },
  "aggs": {
    "models": {
      "terms": { "field": "model" }
    }
  }
}

问题:无法获取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" }
  }
}

优势:

  1. 主查询获取所有Gucci衬衫
  2. colors聚合显示Gucci所有颜色分布
  3. color_red聚合专门统计红色Gucci衬衫的款式
  4. post_filter确保最终结果只显示红色衬衫

搜索结果重评分(Rescore)

重评分机制可以在不增加整体查询负担的情况下,对顶部文档进行更精确的排序。

重评分的工作原理

  1. 首先执行常规查询和过滤
  2. 然后对前N个结果(window_size)进行二次评分
  3. 结合原始分数和重评分得到最终分数

重评分示例

POST /_search
{
  "query": {
    "match": {
      "title": {
        "operator": "or",
        "query": "智能手机 评测"
      }
    }
  },
  "rescore": {
    "window_size": 50,
    "query": {
      "rescore_query": {
        "match_phrase": {
          "title": {
            "query": "智能手机 评测",
            "slop": 2
          }
        }
      },
      "query_weight": 0.7,
      "rescore_query_weight": 1.2
    }
  }
}

分数组合模式

Elasticsearch 提供多种分数组合方式:

模式说明
total原始分与重评分相加(默认)
multiply原始分与重评分相乘
avg取原始分与重评分的平均值
max取原始分与重评分的最大值
min取原始分与重评分的最小值

多阶段重评分

可以设置多个重评分阶段,形成处理管道:

"rescore": [
  {
    "window_size": 100,
    "query": {
      /* 第一阶段重评分 */
    }
  },
  {
    "window_size": 10,
    "query": {
      /* 第二阶段重评分 */
    }
  }
]

最佳实践建议

  1. 在分面导航场景中优先考虑 post_filter
  2. 重评分的 window_size 不宜过大,通常100-500为宜
  3. 分页时保持 window_size 不变,避免结果跳跃
  4. 对于复杂排序需求,可以组合使用多种评分模式
  5. 高并发场景下注意重评分可能带来的性能影响

通过合理运用过滤和重评分机制,可以在保证查询性能的同时,提供更符合用户需求的搜索结果。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值