ElasticSearch如何查询最长的任务

2024-01-09

我在 Elastic Search 中有以下格式的数据:

POST slots/slot/1
{
    taskId:1,
    datetime: "2020-05-10T08:45:44",
    status: "START",
}

POST slots/slot/2
{
    taskId:1,
    datetime: "2020-05-10T08:49:54",
    status: "STOP",
}
...

并想要找到一种方法如何检索前 3 个运行时间最长的任务(这意味着任务,同时存在 START 和 STOP json 对象,并且其 START/STOP 时间之间的差异是最长的) - 我想检索 taskId 和 runningTime ( = 任务运行了多长时间)。

在 ElasticSearch 中可以实现这个任务吗? ElasticSearch 适合此类任务吗?

请宽容一点,我对 ElasticSearch 技术还很陌生。


这个很棘手。我们假设你有恰恰每个 2 个文档unique taskId,其中之一将是START和另一个STOP。在这种情况下,我们可以执行以下操作:

GET slots/_search
{
  "size": 0,
  "aggs": {
    "by_ids": {
      "terms": {
        "field": "taskId",
        "size": 10000,
        "min_doc_count": 2
      },
      "aggs": {
        "start_bucket": {
          "filter": {
            "term": {
              "status.keyword": "START"
            }
          },
          "aggs": {
            "datetime_term": {
              "max": {
                "field": "datetime"
              }
            }
          }
        },
        "stop_bucket": {
          "filter": {
            "term": {
              "status.keyword": "STOP"
            }
          },
          "aggs": {
            "datetime_term": {
              "max": {
                "field": "datetime"
              }
            }
          }
        },
        "diff_in_millis": {
          "bucket_script": {
            "buckets_path": {
              "start": "start_bucket.datetime_term",
              "stop": "stop_bucket.datetime_term"
            },
            "script": "return params.stop - params.start"
          }
        },
        "final_sort": {
          "bucket_sort": {
            "sort": [
              {
                "diff_in_millis": {
                  "order": "desc"
                }
              }
            ],
            "size": 3
          }
        }
      }
    }
  }
}

As per 这次讨论 https://github.com/elastic/elasticsearch/issues/32153,

需要注意的是,这会对最终的存储桶列表进行排序。因此,如果某个术语不在列表中,则不会对其进行排序。这与对术语 agg 本身进行排序相反,后者会更改列表的内容。

换句话说,我们需要设置顶层size任意高,这样我们所有的taskIDs得到聚合。和/或使用仅 2020 年或上个月等的日期过滤器来预过滤上下文,这样我们就可以减少覆盖范围并节省一些 CPU 关键时间。

如果一切顺利并且你的status has a .keyword字段(更多关于此here https://www.elastic.co/blog/strings-are-dead-long-live-strings)我们可以进行过滤,您最终会得到您需要的所有信息:

{
  ...
  "aggregations":{
    "by_ids":{
      "doc_count_error_upper_bound":0,
      "sum_other_doc_count":0,
      "buckets":[
        {
          "key":2,            <-- taskID (this one was added by myself)
          "doc_count":2,
          "start_bucket":{
            ...
          },
          "stop_bucket":{
            ...
          },
          "diff_in_millis":{
            "value":3850000.0        <-- duration in millis
          }
        },
        {
          "key":1,                  <-- task from the question
          "doc_count":2,
          "start_bucket":{
            ...
          },
          "stop_bucket":{
           ...
          },
          "diff_in_millis":{
            "value":250000.0        <-- duration in millis
          }
        }
      ]
    }
  }
}

编辑/更正:

"min_doc_count": 2是需要的,因为我们只对实际完成的任务感兴趣。如果您想包括那些已运行但尚未完成的任务,请创建另一个赏金任务;)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ElasticSearch如何查询最长的任务 的相关文章

随机推荐