深入理解Elasticsearch Pipeline聚集(2)

深入理解Elasticsearch Pipeline聚集(2)

前文中我们讨论管道聚集的结构,带你学习了几个典型的管道聚集类型:导数、累加求和等。

本文我们继续讨论管道聚集分析,主要包括统计、移动平均、移动函数、百分位、分组排序以及分组脚本等。示例数据仍然使用上文中的数据,这里不再说明。

1. 统计管道聚集

在度量聚集中,统计聚集计算索引中数值类型的统计指标,包括最小、最大、平均、求和以及次数。elasticsearch也提供了对其他聚集产生的分组计算统计指标,当stats聚合所需的值必须首先使用其他聚集计算产生每个分组时,则需要使用统计管道聚集。请看示例:

GET /traffic_stats/_search
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                }
            }
        },
        "stats_monthly_visits": {
            "stats_bucket": {
                "buckets_path": "visits_per_month>total_visits" 
            }
        }
    }
}

这个查询首先生成日期直方图,计算所有月份的访问量,生成多个分组;接下来使用stats管道聚集计算这些分组的统计指标,响应结果如下:

{
  "took" : 120,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 27,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2018-10-01T00:00:00.000Z",
          "key" : 1538352000000,
          "doc_count" : 3,
          "total_visits" : {
            "value" : 2060.0
          }
        },
        {
          "key_as_string" : "2018-11-01T00:00:00.000Z",
          "key" : 1541030400000,
          "doc_count" : 3,
          "total_visits" : {
            "value" : 2141.0
          }
        },
        {
          "key_as_string" : "2018-12-01T00:00:00.000Z",
          "key" : 1543622400000,
          "doc_count" : 3,
          "total_visits" : {
            "value" : 2949.0
          }
        },
        {
          "key_as_string" : "2019-01-01T00:00:00.000Z",
          "key" : 1546300800000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 1844.0
          }
        },
        {
          "key_as_string" : "2019-02-01T00:00:00.000Z",
          "key" : 1548979200000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2411.0
          }
        },
        {
          "key_as_string" : "2019-03-01T00:00:00.000Z",
          "key" : 1551398400000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3103.0
          }
        },
        {
          "key_as_string" : "2019-04-01T00:00:00.000Z",
          "key" : 1554076800000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2639.0
          }
        },
        {
          "key_as_string" : "2019-05-01T00:00:00.000Z",
          "key" : 1556668800000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2212.0
          }
        },
        {
          "key_as_string" : "2019-06-01T00:00:00.000Z",
          "key" : 1559347200000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2661.0
          }
        },
        {
          "key_as_string" : "2019-07-01T00:00:00.000Z",
          "key" : 1561939200000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2887.0
          }
        },
        {
          "key_as_string" : "2019-08-01T00:00:00.000Z",
          "key" : 1564617600000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2966.0
          }
        },
        {
          "key_as_string" : "2019-09-01T00:00:00.000Z",
          "key" : 1567296000000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3121.0
          }
        }
      ]
    },
    "stats_monthly_visits" : {
      "count" : 12,
      "min" : 1844.0,
      "max" : 3121.0,
      "avg" : 2582.8333333333335,
      "sum" : 30994.0
    }
  }
}

统计管道聚集执行对日期直方图的每个分组计算各个统计指标,并附加在响应结果的后面。

对于扩展统计聚集逻辑一样,只是返回一些额外指标,如方差、标准差、平方和等,稍微调整下上面的示例使用扩展统计:

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                }
            }
        },
        "stats_monthly_visits": {
            "extended_stats_bucket": {
                "buckets_path": "visits_per_month>total_visits" 
            }
        }
    }
}

响应结果只是最后增加几项指标:

    "stats_monthly_visits" : {
      "count" : 12,
      "min" : 1844.0,
      "max" : 3121.0,
      "avg" : 2582.8333333333335,
      "sum" : 30994.0,
      "sum_of_squares" : 8.21767E7,
      "variance" : 177030.30555555597,
      "std_deviation" : 420.7496946588981,
      "std_deviation_bounds" : {
        "upper" : 3424.3327226511296,
        "lower" : 1741.3339440155373
      }
    }

2. 百分位分组聚集

百分位统计指标表示有多少值落入百分位内,如:第65百分位是65%的观测值位于该值以下。
简单百分位度量聚集计算索引中数值类型字段对于百分位。

一些场景中使用如日期直方图生成分组,然后对这些分组产生的值应用百分位统计。这种情况下即可以基于父聚集也可以基于兄弟聚集计算百分位统计。请看示例:

GET /traffic_stats/_search?size=0
{
  "aggs" : {
    "visits_per_month" : {
      "date_histogram" : {
          "field" : "date",
          "interval" : "month"
      },
      "aggs": {
            "percentiles_monthly_visits": {
              "percentiles": {
                  "field": "visits", 
                  "percents": [ 15.0, 50.0, 75.0, 99.0 ] 
              }
            }
        }
    }
  }
}

这时直接对日期分组内中每个中文档进行百分位计算。下面另一个示例先对每个日期分组求和,在对这些分组和计算百分位:

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                }
            }
        },
        "percentiles_monthly_visits": {
            "percentiles_bucket": {
                "buckets_path": "visits_per_month>total_visits",
                "percents": [ 15.0, 50.0, 75.0, 99.0 ] 
            }
        }
    }
}

与正常百分位统计类似,也可以设置一组百分位,这里设置了15th, 50th, 75th, 99th 四个。运行结果会在追加所有分组的百分位统计:

"percentiles_monthly_visits" : {
    "values" : {
    "15.0" : 2141.0,
    "50.0" : 2661.0,
    "75.0" : 2949.0,
    "99.0" : 3121.0
    }
}

通过结果可以看出所有月份中99%的访问量都在3121次以下。

3. 移动平均聚集

移动平均或滚动平均是一个计算技术,它构造完整数据集的一系列平均值子集。子集通常称为窗口大小。事实上,窗口大小表示每个迭代中数据的数量。在每个迭代中,算法计算窗口内所有数的平均值,然后向前滑动,排除前面子集的第一个数,包括下一个子集的第一个数。这种方法称为移动平均。

举例:给定[1, 5, 8, 23, 34, 28, 7, 23, 20, 19],我们可以计算简单移动平均,设定窗口为5:

  • (1 + 5 + 8 + 23 + 34) / 5 = 14.2
  • (5 + 8 + 23 + 34+ 28) / 5 = 19.6
  • (8 + 23 + 34 + 28 + 7) / 5 = 20
  • ……

移动平均通常用于时间序列数据,抹平短期波动、特出长期趋势。主要为了消除高频波动或随机噪声数据,避免低频趋势明显。

  • 移动平均模型

moving_avg聚集支持5中移动平均模型:simple, linear, exponentially weighted(ewma), holt-linear, holt-winters。这些模型在窗口值的加权方式上有所不同。

随着数据值离现在越远(即窗口从它们滑走),权重可能会变得不同。我们可以通过model参数设置不同模型计算移动平均聚集。

下面章节我们主要讨论 simple, linear, and exponentially weighted (ewma) 三种常用模型,其他模型读者可参考官方文档。

3.1. 简单模型

simple模型首先计算所有窗口内数据值之和,然后除以窗口大小。也就是说,该模型简单计算每个窗口数据集的算数平均数。

下面示例使用simple模型,设置窗口大小为30.聚集将对日期直方图生成的分组计算移动平均。

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                "the_movavg":{
                   "moving_avg":{
                      "buckets_path": "total_visits",
                      "window" : 30,
                      "model" : "simple"
                    }
                 }
            }
        }
    }
}

响应结果为:

"aggregations" : {
    "visits_per_month" : {
      "buckets" : [
       ...
        {
          "key_as_string" : "2019-08-01T00:00:00.000Z",
          "key" : 1564617600000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2966.0
          },
          "the_movavg" : {
            "value" : 2490.7
          }
        },
        {
          "key_as_string" : "2019-09-01T00:00:00.000Z",
          "key" : 1567296000000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3121.0
          },
          "the_movavg" : {
            "value" : 2533.909090909091
          }
        }
      ]
    }
  }

窗口大小能改变移动平均的结果。窗口大小较小时("window": 10),将紧紧遵循原始数据,仅平滑小幅度波动。相反使用较大窗口("window": 100)会平滑所有较高频波动,仅保留低频、长期趋势。它也倾向于比实际数据“滞后”很多。

3.2. 线性模型

该模型对序列中的数据点赋予不同的线性权值。所以旧数据值(即接近窗口开始点)对最终平均计算占比较少。.这种方法用于减少数据平均值背后的“滞后”,因为较早的数据点对最终结果的影响较小。

与简单模型类似,线性模型往往“滞后”于实际数据,虽然比简单模型程度更小。请看下面示例,使用窗口大小30:

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                "the_movavg":{
                   "moving_avg":{
                      "buckets_path": "total_visits",
                      "window" : 30,
                      "model" : "linear"
                    }
                 }
            }
        }
    }
}

响应数据为:

"aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2019-08-01T00:00:00.000Z",
          "key" : 1564617600000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2966.0
          },
          "the_movavg" : {
            "value" : 2539.75
          }
        },
        {
          "key_as_string" : "2019-09-01T00:00:00.000Z",
          "key" : 1567296000000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3121.0
          },
          "the_movavg" : {
            "value" : 2609.731343283582
          }
        }
      ]
    }
  }

3.3. 指数模型

该模型与线性模型逻辑类似,除了对旧数据的权重按照指数递减————不是线性。旧数据的递减速度可以通过alpha参数进行控制。alpha较小权重递减慢,平滑性更好。相反alpha较大使得权重递减更快,减少它们对移动平均线的影响。缺省alpha值为0.3,其值得范围是包括[0~1]之间任何浮点数。

下面示例与上面类似,除了增加额外settings设置alpha

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                "the_movavg":{
                   "moving_avg":{
                      "buckets_path": "total_visits",
                      "window" : 30,
                      "model" : "ewma",
                       "settings": {
                           "alpha": 0.5
                       }
                    }
                 }
            }
        }
    }
}

生成响应结果为:

"aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2019-08-01T00:00:00.000Z",
          "key" : 1564617600000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2966.0
          },
          "the_movavg" : {
            "value" : 2718.958984375
          }
        },
        {
          "key_as_string" : "2019-09-01T00:00:00.000Z",
          "key" : 1567296000000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3121.0
          },
          "the_movavg" : {
            "value" : 2842.4794921875
          }
        }
      ]
    }
  }

3.4. 推断预测

有时基于当前数据的趋势进行预测。所有的移动平均模型都支持预测模型,尝试根据当前平滑的移动平均数来预测未来数据。依赖模型参数,这些预测可能准确也可以不准确。simple, linear 和 ewma模型都产生平滑的预测,收敛于集合中最后一个值的平均值。

使用predict参数指定需要预测几个数值附加在数据序列之后。这些预测将与你预测分组的时间间隔相同。请看示例:

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                "the_movavg":{
                   "moving_avg":{
                      "buckets_path": "total_visits",
                      "window" : 30,
                      "model" : "linear",
                      "predict" : 3
                    }
                 }
            }
        }
    }
}

响应结果在分组列表后面增加三个预测结果:

"aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        ...
        {
          "key_as_string" : "2019-10-01T00:00:00.000Z",
          "key" : 1569888000000,
          "doc_count" : 0,
          "the_movavg" : {
            "value" : 2687.3924050632913
          }
        },
        {
          "key_as_string" : "2019-11-01T00:00:00.000Z",
          "key" : 1572566400000,
          "doc_count" : 0,
          "the_movavg" : {
            "value" : 2687.3924050632913
          }
        },
        {
          "key_as_string" : "2019-12-01T00:00:00.000Z",
          "key" : 1575158400000,
          "doc_count" : 0,
          "the_movavg" : {
            "value" : 2687.3924050632913
          }
        }
      ]
    }
  }

太好了!我们预测网站未来三个月的数据访问量。我们看到预测值很“平稳”,三个月数值相同。如果您希望根据局部的或全局的稳定趋势进行推断,那么应该选择holt模型。

4. 移动函数聚集(6.4之后)

前节介绍的移动平均聚集在6.4之后已不建议使用,可以使用移动函数聚集代替。

与移动平均聚集一样,移动函数聚集也是对数据集的子集进行计算,在数据集上逐渐滑动窗口。但是移动函数可以指定自定义脚本在每个窗口数据上执行。elasticsearch内置提供了一些脚本,如min/max,移动平均等。请看移动函数聚集的标准定义:

{
    "moving_fn": {
        "buckets_path": "the_sum",
        "window": 10,
        "script": "MovingFunctions.min(values)"
    }
}

我们看到定义了一个移动函数聚集在窗口大小为10的数据集上使用内置的min聚集脚本,需要注意的是moving_fn聚集必须嵌入在histogram 或 date_histogram聚集内。

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                   "sum": {
                        "field": "visits"
                    }
                },
                "the_movfn": {
                    "moving_fn": {
                         "buckets_path": "total_visits", 
                         "window": 10,
                         "script": "MovingFunctions.unweightedAvg(values)"
                    }
                }
            }
        }
    }
}

移动函数平均是total_visits聚集的兄弟聚集,visits_per_month的子聚集。上面示例实现simple移动平均计算。

elasticsearch内置聚集脚本有:

  • max()
  • min()
  • sum()
  • stdDev()
  • unweightedAvg()
  • linearWeightedAvg()
  • ewma()
  • holt()
  • holtWinters()

所有函数访问都需要通过MovingFunctions命名空间,如:MovingFunctions.min()

5. 分组选择器聚集

有时根据条件过滤有日期直方图或其他聚集生成的分组。我们可以使用分组选择器聚集,它包括一段脚本决定哪个分组应该被输出。

指定的度量必须是数值型并且脚本必须返回布尔值。

下面示例首先计算每个月访问量之和,然后评估是否大于3000,符合条件则保留在结果集中,否则被过滤。

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                "visits_bucket_filter": {
                   "bucket_selector": {
                       "buckets_path": {
                          "total_visits": "total_visits"
                        },
                    "script": "params.total_visits > 3000"
                  }
              }
         }
      }
   }
}

结果仅保留两个符合规则的分组,响应结果:

{
  "took" : 1646,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 27,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2019-03-01T00:00:00.000Z",
          "key" : 1551398400000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3103.0
          }
        },
        {
          "key_as_string" : "2019-09-01T00:00:00.000Z",
          "key" : 1567296000000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3121.0
          }
        }
      ]
    }
  }
}

6. 分组排序聚集

分组排序是父管道聚集,其针对父多个分组聚集(如日期直方图)返回的分组进行排序。可以指定多个字段进行排序,可以基于_key_count或其子聚集。也能通过设置fromsize参数删除一些分组结果。

下面我们对父日期直方图计算的total_visits值进行排序。按照降序进行排序并返回第一页。

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                "visits_bucket_sort": {
                    "bucket_sort": {
                        "sort": [
                          {"total_visits": {"order": "desc"}}
                        ],
                        "size": 5
                    }
                }
            }
        }
    }
}

响应结果为前5条:

{
  "took" : 15,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 27,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2019-09-01T00:00:00.000Z",
          "key" : 1567296000000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3121.0
          }
        },
        {
          "key_as_string" : "2019-03-01T00:00:00.000Z",
          "key" : 1551398400000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 3103.0
          }
        },
        {
          "key_as_string" : "2019-08-01T00:00:00.000Z",
          "key" : 1564617600000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2966.0
          }
        },
        {
          "key_as_string" : "2018-12-01T00:00:00.000Z",
          "key" : 1543622400000,
          "doc_count" : 3,
          "total_visits" : {
            "value" : 2949.0
          }
        },
        {
          "key_as_string" : "2019-07-01T00:00:00.000Z",
          "key" : 1561939200000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 2887.0
          }
        }
      ]
    }
  }
}

也可以使用该聚集不进行任何排序并删除部分结果,仅需要使用fromsize,不指定sort参数。下面示例仅返回第二、三两个分组:

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                "visits_bucket_sort": {
                    "bucket_sort": {
                        "from": 2,
                        "size": 2
                    }
                }
            }
        }
    }
}

响应结果:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 27,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2018-12-01T00:00:00.000Z",
          "key" : 1543622400000,
          "doc_count" : 3,
          "total_visits" : {
            "value" : 2949.0
          }
        },
        {
          "key_as_string" : "2019-01-01T00:00:00.000Z",
          "key" : 1546300800000,
          "doc_count" : 2,
          "total_visits" : {
            "value" : 1844.0
          }
        }
      ]
    }
  }
}

还可以同时使用选择器和排序:

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "total_visits": {
                    "sum": {
                        "field": "visits"
                    }
                },
                 "visits_bucket_filter": {
                   "bucket_selector": {
                       "buckets_path": {
                          "total_visits": "total_visits"
                        },
                    "script": "params.total_visits > 3000"
                  }
                },
                "visits_bucket_sort": {
                    "bucket_sort": {
                        "from": 0,
                        "size": 2
                    }
                }
            }
        }
    }
}

7. 分组脚本聚集

父管道聚集对每个父级每个分组的度量值执行脚本进行计算。特定度量值必须是数值型,脚本也需返回数值类型。脚本可以是内联的,或在文件、索引中。

下面示例首先对日期直方图分组计算分组中的最大值和最小值,然后通过脚本实现最小值除以最大值计算每个分组中两者的比率:

GET /traffic_stats/_search?size=0
{
    "aggs" : {
        "visits_per_month" : {
            "date_histogram" : {
                "field" : "date",
                "interval" : "month"
            },
            "aggs": {
                "min_visits": {
                    "min": {
                        "field": "visits"
                    }
                },
                "max_visits": {
                    "max": {
                        "field":"visits"
                    }
                },
                "min_max_ratio": {
                   "bucket_script": {
                       "buckets_path": {
                          "min_visits": "min_visits",
                          "max_visits": "max_visits"
                        },
                    "script": "params.min_visits / params.max_visits"
                  }
              }
         }
      }
  }
}

聚集计算每个分组的min_max_ratio,并附加在每个分组之后:

{
  "took" : 170,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 27,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "visits_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2018-10-01T00:00:00.000Z",
          "key" : 1538352000000,
          "doc_count" : 3,
          "min_visits" : {
            "value" : 488.0
          },
          "max_visits" : {
            "value" : 789.0
          },
          "min_max_ratio" : {
            "value" : 0.6185044359949303
          }
        },
        {
          "key_as_string" : "2018-11-01T00:00:00.000Z",
          "key" : 1541030400000,
          "doc_count" : 3,
          "min_visits" : {
            "value" : 394.0
          },
          "max_visits" : {
            "value" : 1299.0
          },
          "min_max_ratio" : {
            "value" : 0.30331023864511164
          }
        },
        {
          "key_as_string" : "2018-12-01T00:00:00.000Z",
          "key" : 1543622400000,
          "doc_count" : 3,
          "min_visits" : {
            "value" : 768.0
          },
          "max_visits" : {
            "value" : 1194.0
          },
          "min_max_ratio" : {
            "value" : 0.6432160804020101
          }
        },
        {
          "key_as_string" : "2019-01-01T00:00:00.000Z",
          "key" : 1546300800000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 872.0
          },
          "max_visits" : {
            "value" : 972.0
          },
          "min_max_ratio" : {
            "value" : 0.897119341563786
          }
        },
        {
          "key_as_string" : "2019-02-01T00:00:00.000Z",
          "key" : 1548979200000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 827.0
          },
          "max_visits" : {
            "value" : 1584.0
          },
          "min_max_ratio" : {
            "value" : 0.5220959595959596
          }
        },
        {
          "key_as_string" : "2019-03-01T00:00:00.000Z",
          "key" : 1551398400000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 1499.0
          },
          "max_visits" : {
            "value" : 1604.0
          },
          "min_max_ratio" : {
            "value" : 0.9345386533665836
          }
        },
        {
          "key_as_string" : "2019-04-01T00:00:00.000Z",
          "key" : 1554076800000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 1247.0
          },
          "max_visits" : {
            "value" : 1392.0
          },
          "min_max_ratio" : {
            "value" : 0.8958333333333334
          }
        },
        {
          "key_as_string" : "2019-05-01T00:00:00.000Z",
          "key" : 1556668800000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 984.0
          },
          "max_visits" : {
            "value" : 1228.0
          },
          "min_max_ratio" : {
            "value" : 0.8013029315960912
          }
        },
        {
          "key_as_string" : "2019-06-01T00:00:00.000Z",
          "key" : 1559347200000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 1238.0
          },
          "max_visits" : {
            "value" : 1423.0
          },
          "min_max_ratio" : {
            "value" : 0.8699929725931131
          }
        },
        {
          "key_as_string" : "2019-07-01T00:00:00.000Z",
          "key" : 1561939200000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 1388.0
          },
          "max_visits" : {
            "value" : 1499.0
          },
          "min_max_ratio" : {
            "value" : 0.9259506337558372
          }
        },
        {
          "key_as_string" : "2019-08-01T00:00:00.000Z",
          "key" : 1564617600000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 1443.0
          },
          "max_visits" : {
            "value" : 1523.0
          },
          "min_max_ratio" : {
            "value" : 0.9474720945502298
          }
        },
        {
          "key_as_string" : "2019-09-01T00:00:00.000Z",
          "key" : 1567296000000,
          "doc_count" : 2,
          "min_visits" : {
            "value" : 1534.0
          },
          "max_visits" : {
            "value" : 1587.0
          },
          "min_max_ratio" : {
            "value" : 0.9666036546943919
          }
        }
      ]
    }
  }
}

8. 总结

你真棒,两节都看完基本已经学完所有的管道聚集,管道聚集实现涉及中间值的复杂计算。你可以利用elasticsearch脚本对返回度量实现自定义编程逻辑。举例:可以评估如果分组匹配一定规则则计算自定义度量,不是缺省内置的逻辑,如最小/最大比率。

发布了395 篇原创文章 · 获赞 761 · 访问量 143万+

猜你喜欢

转载自blog.csdn.net/neweastsun/article/details/104435860