ToB企服应用市场:ToB评测及商务社交产业平台

标题: elasticsearch去重:collapse、cardinality、terms+top_hits实现总结 [打印本页]

作者: 铁佛    时间: 2024-7-10 23:28
标题: elasticsearch去重:collapse、cardinality、terms+top_hits实现总结
码到三十五 :   个人主页  

  
一 、collapse折叠去重

elasticsearch中的collapse功能答应用户对搜索结果进行分组,这在某些环境下可以看作是一种去重利用。它的主要目的是在搜索大量文档时,只表现每个分组的一个代表文档,而不是表现全部匹配的文档。
原理

collapse功能基于一个或多个字段的值对搜索结果进行分组。当你指定了collapse参数后,Elasticsearch会在后台对匹配的文档进行分组,并且每个分组只会返回一个代表文档。这个代表文档通常是分组中的第一个文档,但也可以通过其他参数进行定制。
用法

以下是怎样在Elasticsearch查询中使用collapse的基本示例:
  1. {
  2.   "query": {
  3.     "match": {
  4.       "field": "value"
  5.     }
  6.   },
  7.   "collapse": {
  8.     "field": "group_field"
  9.   }
  10. }
复制代码
在这个示例中:

你还可以通过添加inner_hits参数来定制返回的分组代表文档。比方,假如你想在每个分组中返回评分最高的文档,你可以这样做:
  1. {
  2.   "query": {
  3.     "match": {
  4.       "field": "value"
  5.     }
  6.   },
  7.   "collapse": {
  8.     "field": "group_field",
  9.     "inner_hits": {
  10.       "name": "most_relevant",
  11.       "size": 1,
  12.       "sort": [
  13.         {
  14.           "_score": {
  15.             "order": "desc"
  16.           }
  17.         }
  18.       ]
  19.     }
  20.   }
  21. }
复制代码

注意事项

在使用collapse时,请务必思量这些限定和注意事项,以确保查询的准确性和性能。通过合理规划和优化查询,可以充分利用collapse的分组功能,同时克制潜在的性能瓶颈。
二、字段聚合(terms) + top_hits聚合 去重

结合使用字段聚合(terms)和top_hits聚合可以实现去重功能。
原理

结合这两种聚合,我们可以先按照某个字段进行分组(实现初步的“去重”效果,即每个分组代表一个唯一的字段值),然后在每个分组中使用top_hits聚合返回代表性的文档,从而实现更精致的去重功能。
用法

有一个包罗商品信息的索引,并且你想按照“品牌”字段对商品进行去重,以便每个品牌只表现一个代表性商品。查询大概如下所示:
  1. GET /products/_search
  2. {
  3.   "size": 0, // 不返回具体的匹配文档,只返回聚合结果
  4.   "aggs": {
  5.     "brands": { // terms聚合,按品牌分组
  6.       "terms": {
  7.         "field": "brand",
  8.         "size": 10 // 假设我们想要获取前10个品牌的商品
  9.       },
  10.       "aggs": {
  11.         "top_product": { // 在每个品牌分组内,使用top_hits聚合返回代表性商品
  12.           "top_hits": {
  13.             "size": 1, // 每个品牌只返回一个代表性商品
  14.             "sort": [ // 可以根据需要指定排序方式,例如按评分或价格排序
  15.               {
  16.                 "_score": { // 按评分排序
  17.                   "order": "desc"
  18.                 }
  19.               }
  20.             ]
  21.           }
  22.         }
  23.       }
  24.     }
  25.   }
  26. }
复制代码
我们首先使用terms聚合按照“品牌”字段对商品进行分组,然后在每个分组中使用top_hits聚合返回一个代表性商品(评分最高的商品)。这样,我们就实现了按照品牌对商品进行去重的功能。
三、两种方法的比较

字段聚合(terms)+ top_hits聚合


使用collapse功能


对比总结


在选择使用哪种方法时,应根据具体需求、数据量和性能要求来权衡。假如你需要详细的分组统计信息和多个代表文档,字段聚合+top_hits大概是更好的选择。假如你只需要快速获取每个分组的最佳文档,并且关注性能,那么collapse大概更适合你。
四、cardinality 统计去重后的数目

cardinality聚合是一种用于统计某个字段中不同值的数目基数(即去重后的数目)的功能。
原理


用法

假设你有一个包罗商品销售数据的Elasticsearch索引,你想统计“color”字段中有多少种不同的颜色。你可以使用以下查询来实现:
  1. GET /sales/_search  
  2. {  
  3.   "query": {  
  4.     "range": {  
  5.       "date": {  
  6.         "gte": "2024-01-01",  
  7.         "lte": "2024-06-30"  
  8.       }  
  9.     }  
  10.   },  
  11.   "size": 0,  
  12.   "aggs": {  
  13.     "distinct_colors_in_period": {  
  14.       "cardinality": {  
  15.         "field": "color"  ,
  16.          "precision_threshold": 1000  
  17.       }  
  18.     }  
  19.   }  
  20. }
复制代码
这个查询会返回一个聚合结果,其中包罗“color”字段中不同颜色的数目。
precision_threshold 参数阐明

cardinality 度量是一个近似算法。 它是基于 HyperLogLog++ (HLL)算法的。 HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。
我们不需要理解技能细节, 但我们最好应该关注一下这个算法的 特性 :

要设置精度,我们必须指定 precision_threshold 参数的值。 这个阈值定义了在何种基数程度下我们盼望得到一个近乎精确的结果.

五、collapse + cardinality 实现去重统计和查询

  1. {
  2.     "query": {
  3.         "bool": {
  4.             "filter": [
  5.                 {
  6.                     "range": {
  7.                         "personid": {
  8.                             "lt": "1000000000"
  9.                         }
  10.                     }
  11.                 },
  12.                 {
  13.                     "term": {
  14.                         "isDeleted": "0"
  15.                     }
  16.                 }
  17.             ]
  18.         }
  19.     },
  20.     "collapse": {
  21.         "field": "course_id"
  22.     },
  23.     "from": 0,
  24.     "size": 10,
  25.     "track_total_hits": true,
  26.     "aggs": {
  27.         "courseAgg": {
  28.             "cardinality": {
  29.                 "field": "course_id"
  30.             }
  31.         }
  32.     }
  33. }
复制代码
返回结果
  1. {
  2.     "took": 140,
  3.     "timed_out": false,
  4.     "_shards": {
  5.         "total": 6,
  6.         "successful": 6,
  7.         "skipped": 0,
  8.         "failed": 0
  9.     },
  10.     "hits": {
  11.         "total": {
  12.             "value": 2111,
  13.             "relation": "eq"
  14.         },
  15.         "max_score": 0.0,
  16.         "hits": [...]
  17.     },
  18.     "aggregations": {
  19.         "courseAgg": {
  20.             "value": 1070
  21.         }
  22.     }
  23. }
复制代码
解释阐明

    关注以下公众号获取更多深度内容,纯干货 !   


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4