使用 Elasticsearch 的 Field Collapsing

在大多数搜索应用程序中,尤其是在电商、社交媒体或内容聚合平台中,我们常常遇到这样一个需求:希望将具有相同属性(例如同一商品的不同规格、同一作者的不同文章等)的搜索结果合并或折叠在一起,而不是显示冗余的重复项。Elasticsearch 提供了一个强大的功能来实现这一需求:Field Collapsing。本文将详细介绍 Elasticsearch 的 Field Collapsing 功能及其使用场景。

什么是 Field Collapsing?

Field Collapsing 是 Elasticsearch 7.x 版本开始引入的一个特性,它允许你将搜索结果按照某个字段的值进行折叠。折叠的结果中,每个唯一字段值只会显示一个文档,而不是展示所有匹配的文档。这在需要去重、分组展示或提高结果精简度时非常有用。

典型应用场景

  1. 商品搜索:在电商平台上,同一商品可能有多个规格或颜色。如果不做折叠,用户在搜索时可能会看到多个几乎相同的结果。使用 Field Collapsing,可以只展示每个商品的一个结果,而不是多个规格版本。

  2. 内容聚合:在新闻或社交媒体平台中,同一作者可能发布多篇相似内容。折叠可以确保每个作者只展示一个结果,而不是所有文章。

  3. 数据去重:对于某些场景,特别是去重场景,Field Collapsing 可以直接根据指定字段折叠相同的文档,减少重复结果。

Field Collapsing 的工作原理

Field Collapsing 的核心在于通过一个字段来对结果集进行分组和折叠。在 Elasticsearch 的查询中,可以通过 collapse 参数实现这一功能。该参数通常配合 inner_hits 来展示每个折叠组中的具体文档信息。

基本用法

我们来看看如何在 Elasticsearch 查询中使用 Field Collapsing。

示例场景:商品搜索

假设我们有一个商品索引,其中包含多个规格的同一商品。我们希望在用户搜索时,只展示每个商品的一个版本,而不是显示所有规格。

索引示例

POST /products/_bulk
{ "index": { "_id": "1" } }
{ "name": "iPhone 12", "color": "black", "price": 699 }
{ "index": { "_id": "2" } }
{ "name": "iPhone 12", "color": "white", "price": 699 }
{ "index": { "_id": "3" } }
{ "name": "iPhone 12", "color": "red", "price": 699 }
{ "index": { "_id": "4" } }
{ "name": "Samsung Galaxy S21", "color": "black", "price": 799 }
{ "index": { "_id": "5" } }
{ "name": "Samsung Galaxy S21", "color": "white", "price": 799 }

查询示例

为了折叠具有相同商品名称的结果,我们可以使用如下的查询:

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "collapse": {
    "field": "name.keyword"
  }
}

结果解释

上述查询中,collapse 参数指定了 name.keyword 字段。查询结果会根据该字段的唯一值进行折叠,每个唯一值只会返回一个文档。这意味着,对于 iPhone 12,无论有多少个颜色规格,只会返回一个结果。

{
  "hits": {
    "hits": [
      {
        "_id": "1",
        "_source": {
          "name": "iPhone 12",
          "color": "black",
          "price": 699
        }
      },
      {
        "_id": "4",
        "_source": {
          "name": "Samsung Galaxy S21",
          "color": "black",
          "price": 799
        }
      }
    ]
  }
}

在这个结果中,我们只看到了每个产品系列中的一个条目,而不是所有规格。

使用 Inner Hits 查看折叠组中的其他文档

有时候,我们不仅仅希望看到折叠后的结果,还想查看每个折叠组中其他的文档。Elasticsearch 提供了 inner_hits 参数来满足这一需求。

示例查询

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "collapse": {
    "field": "name.keyword",
    "inner_hits": {
      "name": "related_variants",
      "size": 3
    }
  }
}

结果解释

在上述查询中,inner_hits 参数让我们能够查看每个折叠组中的其他文档。结果中,除了主文档外,还会包含一个 inner_hits 字段,展示该组内的其他文档。

{
  "hits": {
    "hits": [
      {
        "_id": "1",
        "_source": {
          "name": "iPhone 12",
          "color": "black",
          "price": 699
        },
        "inner_hits": {
          "related_variants": {
            "hits": {
              "hits": [
                {
                  "_id": "2",
                  "_source": {
                    "name": "iPhone 12",
                    "color": "white",
                    "price": 699
                  }
                },
                {
                  "_id": "3",
                  "_source": {
                    "name": "iPhone 12",
                    "color": "red",
                    "price": 699
                  }
                }
              ]
            }
          }
        }
      },
      {
        "_id": "4",
        "_source": {
          "name": "Samsung Galaxy S21",
          "color": "black",
          "price": 799
        },
        "inner_hits": {
          "related_variants": {
            "hits": {
              "hits": [
                {
                  "_id": "5",
                  "_source": {
                    "name": "Samsung Galaxy S21",
                    "color": "white",
                    "price": 799
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

在这里,你可以看到 iPhone 12 的主结果(黑色款)和相关的其他两个颜色(白色和红色)。

Field Collapsing 的限制

  1. 不能与聚合一起使用:Field Collapsing 不能与某些聚合查询(如 terms 聚合)直接配合使用。这是因为聚合是在全局范围内执行的,而 Field Collapsing 仅对返回的结果集生效。

  2. 不适合深度分页:当进行深度分页时,Field Collapsing 的性能会下降。对于需要深度分页的场景,可以考虑使用滚动分页(scroll)或其他优化方案。

  3. 无法在分片之间折叠:Field Collapsing 是在单个分片内完成的。这意味着同一字段值可能出现在不同的分片中,导致未完全折叠的情况。

总结

Elasticsearch 的 Field Collapsing 是一个强大而实用的功能,尤其适用于需要将重复或相似的结果折叠在一起的场景。通过简单的配置,你可以显著提高搜索结果的简洁度和用户体验。同时,借助 inner_hits 参数,你还可以灵活地展示折叠组中的其他相关文档。

在使用 Field Collapsing 时,需要考虑其与聚合查询的兼容性以及深度分页的性能影响。在合适的场景下,Field Collapsing 可以帮助你构建更高效、更友好的搜索应用。

希望本文能帮助你更好地理解和使用 Elasticsearch 的 Field Collapsing 功能。如果你在实际项目中有更多的需求或疑问,欢迎进一步探讨与交流。

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值