从零开发短视频电商 OpenSearch/Elasticsearch 聚合操作

文章目录

OpenSearch不仅仅是用于搜索的工具。聚合使您能够利用OpenSearch强大的分析引擎分析数据并从中提取统计信息。

聚合的用例各异,从实时分析数据以采取某些行动,到使用OpenSearch仪表板创建可视化仪表板。

OpenSearch可以在毫秒内对大规模数据集执行聚合。与查询相比,聚合消耗更多的CPU周期和内存。

先来个总结表格

聚合类型 Elasticsearch SQL
指标聚合(Metric Aggregations)
平均值(Average) avg SELECT AVG(column) FROM table;
基数(Cardinality) cardinality SELECT COUNT(DISTINCT column) FROM table;
扩展统计(Extended Stats) extended_stats SELECT AVG(column), MIN(column), MAX(column), COUNT(column) FROM table;
地理边界(Geobounds) geobounds 无SQL对应,用于地理坐标范围的统计。
矩阵统计(Matrix Stats) matrix_stats 无SQL对应,用于多值字段的统计。
最大值(Maximum) max SELECT MAX(column) FROM table;
最小值(Minimum) min SELECT MIN(column) FROM table;
百分位排名(Percentile Ranks) percentiles_rank SELECT PERCENTILE_CONT(percentage) WITHIN GROUP (ORDER BY column) FROM table;
百分位(Percentile) percentiles SELECT PERCENTILE_CONT(percentage) WITHIN GROUP (ORDER BY column) FROM table;
脚本度量(Scripted Metric) scripted_metric 无SQL对应,通过自定义脚本计算度量。
统计信息(Stats) stats SELECT AVG(column), MIN(column), MAX(column), COUNT(column), SUM(column) FROM table;
求和(Sum) sum SELECT SUM(column) FROM table;
前N条记录(Top Hits) top_hits 无SQL对应,返回每个桶中排序后的前N条记录。
值计数(Value Count) value_count SELECT COUNT(column) FROM table;
桶聚合(Bucket Aggregations) Elasticsearch SQL
邻接矩阵(Adjacency Matrix) adjacency_matrix 无SQL对应,用于关系型数据的统计。
日期直方图(Date Histogram) date_histogram SELECT COUNT(column), DATE_TRUNC('interval', date_column) FROM table GROUP BY DATE_TRUNC('interval', date_column);
日期范围(Date Range) date_range SELECT COUNT(column) FROM table WHERE date_column BETWEEN start_date AND end_date;
多样化采样(Diversified Sampler) diversified_sampler 无SQL对应,用于多样本的统计。
过滤器(Filter) filter SELECT COUNT(column) FROM table WHERE condition;
多过滤器(Filters) filters 无SQL对应,用于同时应用多个过滤器的统计。
地理距离(Geodistance) geodistance 无SQL对应,用于地理坐标距离的统计。
地理哈希网格(Geohash Grid) geohash_grid 无SQL对应,用于地理坐标哈希网格的统计。
地理六边形网格(Geohex Grid) geohex_grid 无SQL对应,用于地理坐标六边形网格的统计。
地理瓦片网格(Geotile Grid) geotile_grid 无SQL对应,用于地理坐标瓦片网格的统计。
全局(Global) global 无SQL对应,用于对整个数据集执行聚合而不分组。
直方图(Histogram) histogram SELECT COUNT(column), FLOOR(column/interval)*interval as range FROM table GROUP BY range;
IP范围(IP Range) ip_range 无SQL对应,用于IP地址范围的统计。
缺失值(Missing) missing SELECT COUNT(column) FROM table WHERE column IS NULL;
多词项(Multi-terms) multi_terms 无SQL对应,用于多个词项的统计。
嵌套(Nested) nested 无SQL对应,用于嵌套文档的统计。
范围(Range) range SELECT COUNT(column) FROM table WHERE column BETWEEN min AND max;
反向嵌套(Reverse Nested) reverse_nested 无SQL对应,用于反向嵌套文档的统计。
采样器(Sampler) sampler 无SQL对应,用于对样本进行统计。
显著项(Significant Terms) significant_terms 无SQL对应,用于显著项的统计。
显著文本(Significant Text) significant_text 无SQL对应,用于显著文本的统计。
词项(Terms) terms SELECT COUNT(column) FROM table GROUP BY column;

文本字段上的聚合

默认情况下,OpenSearch不支持在文本字段上进行聚合。因为文本字段被标记化,对文本字段的聚合必须将标记化过程反转回其原始字符串,然后基于此进行聚合。这种操作消耗大量内存并降低集群性能。

虽然您可以通过在映射中将 fielddata 参数设置为 true 来启用文本字段的聚合,但聚合仍然基于标记化单词而不是原始文本。

我们建议将文本字段的原始版本保留为可聚合的 keyword 字段。

在这种情况下,您可以对 title.raw 字段而不是 title 字段执行聚合:

json 复制代码
PUT movies
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fielddata": true,
        "fields": {
          "raw": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

通用聚合结构

聚合查询的结构如下:

json 复制代码
GET _search
{
  "size": 0,
  "aggs": {
    "NAME": {
      "AGG_TYPE": {}
    }
  }
}

如果您只对聚合结果感兴趣而不对查询结果感兴趣,请将 size 设置为 0。

aggs 属性中(如果需要,可以使用 aggregations ),您可以定义任意数量的聚合。每个聚合均由其名称和 OpenSearch 支持的聚合类型之一定义。

聚合的名称可帮助您区分响应中的不同聚合。 AGG_TYPE 属性是您指定聚合类型的位置。

嵌套聚合

聚合内的聚合称为嵌套聚合或子聚合。

指标聚合产生简单的结果,并且不能包含嵌套聚合。

存储桶聚合生成可以嵌套在其他聚合中的文档存储桶。您可以通过在存储桶聚合中嵌套指标和存储桶聚合来对数据执行复杂的分析。

通用嵌套聚合语法

json 复制代码
{
  "aggs": {
    "name": {
      "type": {
        "data"
      },
      "aggs": {
        "nested": {
          "type": {
            "data"
          }
        }
      }
    }
  }
}

内部 aggs 关键字开始新的嵌套聚合。父聚合和嵌套聚合的语法相同。嵌套聚合在前面的父聚合的上下文中运行。

您还可以将聚合与搜索查询配对,以缩小聚合之前尝试分析的范围。如果您不添加查询,OpenSearch 会隐式使用 match_all 查询。

由于聚合器对所有值都使用 double 数据类型进行处理,因此 2 53 及更大的 long 值是近似值。

聚合类型

聚合主要分为三种类型:

  • 指标聚合 - 计算数字字段上的指标,例如 summinmaxavg
  • 桶聚合 - 根据某些标准对查询结果进行分组。
  • 管道聚合 - 将一个聚合的输出作为另一个聚合的输入。

指标聚合

指标聚合可让您执行简单的计算,例如查找字段的最小值、最大值和平均值。

度量聚合有两种类型:单值度量聚合和多值度量聚合。

  • 单值指标聚合返回单个指标,例如 summinmaxavgcardinality
  • 多值指标聚合返回多个指标。这些包括 statsextended_statsmatrix_statspercentilepercentile_ranksgeo_boundtop_hitsscripted_metric

平均值/求和等

要查找 taxful_total_price 字段的平均值:

json 复制代码
GET opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "avg_taxful_total_price": { // 这个名字可以随意定义
      "avg": {  // 求平均值
        "field": "taxful_total_price" // 在taxful_total_price字段上 操作
      }
    }
  }
}

响应示例

json 复制代码
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4675,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "avg_taxful_total_price" : { // 呼应前面定义的名称
      "value" : 75.05542864304813
    }
  }
}

基数

cardinality 指标是单值指标聚合,用于计算字段的唯一或不同值的数量。

json 复制代码
GET opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "unique_products": {
      "cardinality": {
        "field": "products.product_id"
      }
    }
  }
}

...
  "aggregations" : {
    "unique_products" : {
      "value" : 7033
    }
  }
}

基数计数是近似值。如果您的假设商店中有数万种产品,则准确的基数计算需要将所有值加载到哈希集中并返回其大小。这种方法的扩展性不好;它需要大量内存并可能导致高延迟。

您可以使用 precision_threshold 设置来控制内存和准确性之间的权衡。此设置定义阈值,低于该阈值计数预计接近准确。高于此值,计数可能会变得不太准确。 precision_threshold 的默认值为 3,000。支持的最大值为 40,000。

json 复制代码
GET opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "unique_products": {
      "cardinality": {
        "field": "products.product_id",
        "precision_threshold": 10000
      }
    }
  }
}

百分位

json 复制代码
GET opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "percentile_taxful_total_price": {
      "percentiles": {
        "field": "taxful_total_price"
      }
    }
  }
}
...
"aggregations" : {
  "percentile_taxful_total_price" : {
    "values" : {
      "1.0" : 21.984375,
      "5.0" : 27.984375,
      "25.0" : 44.96875,
      "50.0" : 64.22061688311689,
      "75.0" : 93.0,
      "95.0" : 156.0,
      "99.0" : 222.0
    }
  }
 }
}

统计汇总

stats 指标是一个多值指标聚合,它返回所有基本指标,例如 minmaxsumavgvalue_count 在一个聚合查询中。

json 复制代码
GET opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "stats_taxful_total_price": {
      "stats": {
        "field": "taxful_total_price"
      }
    }
  }
}
...
"aggregations" : {
  "stats_taxful_total_price" : {
    "count" : 4675,
    "min" : 6.98828125,
    "max" : 2250.0,
    "avg" : 75.05542864304813,
    "sum" : 350884.12890625
  }
 }
}

热门点击

top_hits 指标是一种多值指标聚合,它根据正在聚合的字段的相关性得分对匹配文档进行排名。

from :命中的起始位置。

size :返回的最大命中数。默认值为 3。

sort :匹配的命中如何排序。默认情况下,命中按聚合查询的相关性分数排序。

以下示例返回电子商务数据中排名前 5 的产品:

json 复制代码
GET opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "top_hits_products": {
      "top_hits": {
        "size": 5
      }
    }
  }
}
...
"aggregations" : {
  "top_hits_products" : {
    "hits" : {
      "total" : {
        "value" : 4675,
        "relation" : "eq"
      },
      "max_score" : 1.0,
      "hits" : [
        {
          "_index" : "opensearch_dashboards_sample_data_ecommerce",
          "_type" : "_doc",
          "_id" : "glMlwXcBQVLeQPrkHPtI",
          "_score" : 1.0,
          "_source" : {
            "category" : [
              "Women's Accessories",
              "Women's Clothing"
            ],
            "currency" : "EUR",
            "customer_first_name" : "rania",
            "customer_full_name" : "rania Evans",
            "customer_gender" : "FEMALE",
            "customer_id" : 24,
            "customer_last_name" : "Evans",
            "customer_phone" : "",
            "day_of_week" : "Sunday",
            "day_of_week_i" : 6,
            "email" : "rania@evans-family.zzz",
            "manufacturer" : [
              "Tigress Enterprises"
            ],
            "order_date" : "2021-02-28T14:16:48+00:00",
            "order_id" : 583581,
            "products" : [
              {
                "base_price" : 10.99,
                "discount_percentage" : 0,
                "quantity" : 1,
                "manufacturer" : "Tigress Enterprises",
                "tax_amount" : 0,
                "product_id" : 19024,
                "category" : "Women's Accessories",
                "sku" : "ZO0082400824",
                "taxless_price" : 10.99,
                "unit_discount_amount" : 0,
                "min_price" : 5.17,
                "_id" : "sold_product_583581_19024",
                "discount_amount" : 0,
                "created_on" : "2016-12-25T14:16:48+00:00",
                "product_name" : "Snood - white/grey/peach",
                "price" : 10.99,
                "taxful_price" : 10.99,
                "base_unit_price" : 10.99
              },
              {
                "base_price" : 32.99,
                "discount_percentage" : 0,
                "quantity" : 1,
                "manufacturer" : "Tigress Enterprises",
                "tax_amount" : 0,
                "product_id" : 19260,
                "category" : "Women's Clothing",
                "sku" : "ZO0071900719",
                "taxless_price" : 32.99,
                "unit_discount_amount" : 0,
                "min_price" : 17.15,
                "_id" : "sold_product_583581_19260",
                "discount_amount" : 0,
                "created_on" : "2016-12-25T14:16:48+00:00",
                "product_name" : "Cardigan - grey",
                "price" : 32.99,
                "taxful_price" : 32.99,
                "base_unit_price" : 32.99
              }
            ],
            "sku" : [
              "ZO0082400824",
              "ZO0071900719"
            ],
            "taxful_total_price" : 43.98,
            "taxless_total_price" : 43.98,
            "total_quantity" : 2,
            "total_unique_products" : 2,
            "type" : "order",
            "user" : "rani",
            "geoip" : {
              "country_iso_code" : "EG",
              "location" : {
                "lon" : 31.3,
                "lat" : 30.1
              },
              "region_name" : "Cairo Governorate",
              "continent_name" : "Africa",
              "city_name" : "Cairo"
            },
            "event" : {
              "dataset" : "sample_ecommerce"
            }
          }
          ...
        }
      ]
    }
  }
 }
}

值计数

value_count 指标是单值指标聚合,用于计算聚合所基于的值的数量。

json 复制代码
GET opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
   "aggs": {
    "number_of_values": {
      "value_count": {
        "field": "taxful_total_price"
      }
    }
  }
}

...
  "aggregations" : {
    "number_of_values" : {
      "value" : 4675
    }
  }
}

桶聚合

存储桶聚合将文档集分类为存储桶。存储桶聚合的类型决定了给定文档的存储桶。

日期直方图

date_histogram聚合使用日期数学来生成时间序列数据的直方图。

网站每月获得的点击次数

json 复制代码
GET opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "logs_per_month": {
      "date_histogram": {
        "field": "@timestamp",
        "interval": "month"
      }
    }
  }
}

...
"aggregations" : {
  "logs_per_month" : {
    "buckets" : [
      {
        "key_as_string" : "2020-10-01T00:00:00.000Z",
        "key" : 1601510400000,
        "doc_count" : 1635
      },
      {
        "key_as_string" : "2020-11-01T00:00:00.000Z",
        "key" : 1604188800000,
        "doc_count" : 6844
      },
      {
        "key_as_string" : "2020-12-01T00:00:00.000Z",
        "key" : 1606780800000,
        "doc_count" : 5595
      }
    ]
  }
}
}

直方图

histogram 聚合根据指定的时间间隔存储文档。

通过 histogram 聚合,您可以非常轻松地可视化给定文档范围内的值的分布。当然,现在 OpenSearch 不会返回实际的图表,这就是 OpenSearch 仪表板的用途。但它会给你 JSON 响应,你可以用它来构建你自己的图表。

以下示例按 10,000 个间隔对 number_of_bytes 字段进行存储:

json 复制代码
GET opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "number_of_bytes": {
      "histogram": {
        "field": "bytes",
        "interval": 10000
      }
    }
  }
}

...
"aggregations" : {
  "number_of_bytes" : {
    "buckets" : [
      {
        "key" : 0.0,
        "doc_count" : 13372
      },
      {
        "key" : 10000.0,
        "doc_count" : 702
      }
    ]
  }
 }
}

范围聚合

range 聚合允许您定义每个存储桶的范围。

例如,您可以查找 1000 到 2000、2000 到 3000、3000 到 4000 之间的字节数。在 range 参数中,您可以将范围定义为数组对象。

json 复制代码
GET opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "number_of_bytes_distribution": {
      "range": {
        "field": "bytes",
        "ranges": [
          {
            "from": 1000,
            "to": 2000
          },
          {
            "from": 2000,
            "to": 3000
          },
          {
            "from": 3000,
            "to": 4000
          }
        ]
      }
    }
  }
}

...
"aggregations" : {
  "number_of_bytes_distribution" : {
    "buckets" : [
      {
        "key" : "1000.0-2000.0",
        "from" : 1000.0,
        "to" : 2000.0,
        "doc_count" : 805
      },
      {
        "key" : "2000.0-3000.0",
        "from" : 2000.0,
        "to" : 3000.0,
        "doc_count" : 1369
      },
      {
        "key" : "3000.0-4000.0",
        "from" : 3000.0,
        "to" : 4000.0,
        "doc_count" : 1422
      }
    ]
  }
 }
}

词语聚合

terms 聚合动态地为字段的每个唯一术语创建一个存储桶。

以下示例使用 terms 聚合来查找 Web 日志数据中每个响应代码的文档数:

json 复制代码
GET opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "response_codes": {
      "terms": {
        "field": "response.keyword",
        "size": 10
      }
    }
  }
}

...
"aggregations" : {
  "response_codes" : {
    "doc_count_error_upper_bound" : 0,
    "sum_other_doc_count" : 0,
    "buckets" : [
      {
        "key" : "200",
        "doc_count" : 12832
      },
      {
        "key" : "404",
        "doc_count" : 801
      },
      {
        "key" : "503",
        "doc_count" : 441
      }
    ]
  }
 }
}
相关推荐
Lostgreen8 分钟前
分布式查询处理优化之数据分片
大数据·笔记·分布式
夏子曦10 分钟前
java虚拟机——频繁发生Full GC的原因有哪些?如何避免发生Full GC
java·开发语言
gogo_hua11 分钟前
JVM系列之OOM观测准备
java·大数据·jvm
m0_6754470822 分钟前
Solon 拉取 maven 包很慢或拉不了,怎么办?
java·maven
武昌库里写JAVA26 分钟前
SpringCloud+SpringCloudAlibaba学习笔记
java·开发语言·算法·spring·log4j
爱编程的小生28 分钟前
SpringBoot Task
java·spring boot·后端
CoderJia程序员甲35 分钟前
重学SpringBoot3-异步编程完全指南
java·spring boot·后端·异步编程
小咖拉眯38 分钟前
第十六届蓝桥杯模拟赛第二期题解—Java
java·数据结构·算法·蓝桥杯·图搜索算法
扬子鳄00838 分钟前
Spring Boot自动配置机制
java·数据库·spring boot
岁岁岁平安40 分钟前
springboot实战(19)(条件分页查询、PageHelper、MYBATIS动态SQL、mapper映射配置文件、自定义类封装分页查询数据集)
java·spring boot·后端·mybatis·动态sql·pagehelper·条件分页查询