Elasticsearch权威指南:使用Top Hits聚合实现字段折叠分组查询

Elasticsearch权威指南:使用Top Hits聚合实现字段折叠分组查询

elasticsearch-definitive-guide The Definitive Guide to Elasticsearch elasticsearch-definitive-guide 项目地址: https://gitcode.com/gh_mirrors/el/elasticsearch-definitive-guide

什么是字段折叠

字段折叠(Field Collapsing)是搜索场景中一个常见需求,它允许我们将搜索结果按照某个特定字段进行分组展示。比如在博客系统中,我们可能需要按照作者姓名分组显示最相关的博客文章。

实现原理

Elasticsearch通过组合使用terms聚合和top_hits聚合来实现这一功能:

  1. terms聚合:负责按照指定字段值进行分组
  2. top_hits聚合:在每个分组内返回最相关的文档

准备工作

索引映射设置

要实现有效的分组,分组字段必须是未经分析的原始值。我们通常使用多字段(multi-field)映射:

PUT /my_index/_mapping/blogpost
{
  "properties": {
    "user": {
      "properties": {
        "name": {
          "type": "string",
          "fields": {
            "raw": {
              "type":  "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}
  • user.name:用于全文搜索的分析字段
  • user.name.raw:用于分组的原始字段

测试数据准备

PUT /my_index/user/1
{
  "name": "John Smith",
  "email": "john@smith.com",
  "dob": "1970/10/24"
}

PUT /my_index/blogpost/2
{
  "title": "Relationships",
  "body": "It's complicated...",
  "user": {
    "id": 1,
    "name": "John Smith"
  }
}

PUT /my_index/user/3
{
  "name": "Alice John",
  "email": "alice@john.com",
  "dob": "1979/01/04"
}

PUT /my_index/blogpost/4
{
  "title": "Relationships are cool",
  "body": "It's not complicated at all...",
  "user": {
    "id": 3,
    "name": "Alice John"
  }
}

执行分组查询

下面是一个完整的字段折叠查询示例:

GET /my_index/blogpost/_search 
{
  "size" : 0,
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "relationships" }},
        { "match": { "user.name": "John" }}
      ]
    }
  },
  "aggs": {
    "users": {
      "terms": {
        "field": "user.name.raw",
        "order": { "top_score": "desc" }
      },
      "aggs": {
        "top_score": { "max": { "script": "_score" }},
        "blogposts": { "top_hits": { "_source": "title", "size": 5 }}
      }
    }
  }
}

关键参数说明

  1. "size": 0:不返回常规搜索结果,只返回聚合结果
  2. query:筛选标题包含"relationships"且用户名为"John"的博客
  3. terms聚合:按用户原始姓名分组
  4. top_score子聚合:计算每个分组中最高文档得分,用于排序
  5. top_hits子聚合:返回每个分组中最相关的5篇博客标题

结果解析

响应结果主要包含两部分:

  1. 空hits数组:因为我们设置了"size":0
  2. 聚合结果
    • 每个用户一个分组桶(bucket)
    • 每个桶包含:
      • 用户姓名(key)
      • 文档数量(doc_count)
      • 该用户最相关的博客列表(blogposts.hits)
      • 该组最高得分(top_score)

性能优势

使用top_hits聚合比传统方法(先查询用户列表,再为每个用户单独查询)效率高得多,因为:

  1. 只需一次查询请求
  2. Elasticsearch内部优化了执行过程
  3. 支持分页、高亮等常规搜索特性

实际应用场景

字段折叠技术非常适合以下场景:

  1. 电商网站按商家展示商品
  2. 新闻网站按分类展示文章
  3. 论坛按话题展示帖子
  4. 任何需要分组展示搜索结果的场景

通过合理使用top_hits聚合,可以显著提升搜索体验和系统性能。

elasticsearch-definitive-guide The Definitive Guide to Elasticsearch elasticsearch-definitive-guide 项目地址: https://gitcode.com/gh_mirrors/el/elasticsearch-definitive-guide

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

廉咏燃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

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

抵扣说明:

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

余额充值