【问题标题】:sorting results of aggregation in elasticsearchelasticsearch中聚合的排序结果
【发布时间】:2019-02-03 10:58:57
【问题描述】:

我已经编写了一个查询来从我的 ES 中获取每个 Id 的最新记录。 但是这个查询的结果只做内部排序,选择最新的记录。现在我需要按日期排序的结果。

这是我的查询:

{
   "size":0,
   "query":{
      "bool":{
         "must":[
            {
               "match":{
                  "base":"XYZ"
               }
            },
            {
               "match":{
                  "Type":"low"
               }
            }
         ]
      }
   },
   "aggs":{
      "sources":{
         "terms":{
            "field":"Id"
         },
         "aggs":{
            "latest":{
               "top_hits":{
                  "size":1,

                  "_source":{
                     "includes":[
                        "base",
                        "Type"
                     ]
                  },
                  "sort":{
                     "orderDate":"desc"
                  }
               }
            }
         }
      }
   }
}

【问题讨论】:

  • 请分享一个示例文档和索引映射
  • 示例文档:{“_index”:“XXXX”,“_type”:“logs”,“_id”:“bGd3qWgBnyB5Q6tB0Zjb”,“_version”:1,“_score”:null,“_source ": { "qtyFulfilled": 1.5, "@timestamp": "2019-02-01T14:30:27.784Z", "base": "BTC", "Type": "LIMIT", }, "fields": { “@timestamp”:[“2019-02-01T14:30:27.784Z”],“orderDate”:[“2019-02-01T14:30:27.727Z”]}
  • 我的查询结果为我提供了每个 ID 的最新文档。比如 id 1 是最新的文档,然后 id 2 是最新的文档。但我也需要对这个最终结果的顺序进行排序。就像对聚合结果的排序一样。
  • 您好,您分享了查询结果。我想知道您查询的所有字段在存储在弹性文件中的文档中的外观。

标签: elasticsearch


【解决方案1】:

您尝试做的是按另一个桶对桶进行排序。您可以通过两种方式实现这一目标:

(a) 由bucket_sort 聚合

(b) 使用 order 参数聚合引用另一个存储桶的术语。

(a) bucket_sort 聚合

此聚合对其父多存储桶聚合的存储桶进行排序。您可以指定对存储桶进行排序的字段。使用它,您的案例的查询将是:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "base": "XYZ"
          }
        },
        {
          "match": {
            "Type": "low"
          }
        }
      ]
    }
  },
  "aggs": {
    "source": {
      "terms": {
        "field": "id"
      },
      "aggs": {
        "latest": {
          "top_hits": {
            "size": 1,
            "_source": {
              "includes": [
                "base",
                "Type"
              ]
            },
            "sort": {
              "orderDate": "desc"
            }
          }
        },
        "latestOrder": {
          "max": {
            "field": "orderDate"
          }
        },
        "bucket_sort_order": {
          "bucket_sort": {
            "sort": {
              "latestOrder": {
                "order": "desc"
              }
            }
          }
        }
      }
    }
  },
  "post_filter": {
    "term": {
      "status": "yes"
    }
  }
}

在上面的查询中,我使用了一个名为 latestOrder 的最大聚合。这个聚合为我们提供了最新的orderDate 的值。如果我们将其视为热门聚合,则它返回的文档将具有与最大聚合返回的相同的 orderDate,即 latestOrder。原因是我们在 desc 中按 orderDate 排序了 top hit 并将大小限制为 1,相当于 max orderDate

latestOrder 对我们来说是一个排序字段,然后在bucket_sort 聚合中使用它来对由术语聚合返回的桶的父桶进行排序。

(b) order 参数 agg

我们使用与上述类似的方法。我们使用最大聚合latestOrder 并在术语聚合的order 参数中引用它。所以查询将是:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "base": "XYZ"
          }
        },
        {
          "match": {
            "Type": "low"
          }
        }
      ]
    }
  },
  "aggs": {
    "source": {
      "terms": {
        "field": "id",
        "order": {
          "latestOrder": "desc"
        }
      },
      "aggs": {
        "latest": {
          "top_hits": {
            "size": 1,
            "_source": {
              "includes": [
                "base",
                "Type",
                "orderDate"
              ]
            },
            "sort": {
              "orderDate": "desc"
            }
          }
        },
        "latestOrder": {
          "max": {
            "field":"orderDate"
          }
        }
      }
    }
  },
  "post_filter": {
    "term": {
      "status": "yes"
    }
  }
}

查询中的更新:根据 cmets 中的讨论添加了 post_filter。

【讨论】:

  • 我可以过滤我从上述聚合中得到的结果,只得到带有 base="xyz" 的文档吗?我试过 post_filter 和 bucket_filters 但没有成功。
  • 它也在做同样的事情。我没有更改您用来过滤结果的查询。查询已经有一个匹配 base="XYZ" 的条件。您可以将 XYZ 更改为 xyz。
  • 另外,如果它解决了您的问题,我请求您点赞并接受答案。
  • 这是一个示例数据。我需要根据存储桶中的术语查询我得到的结果。我之前所做的查询是必需的,并且基于该结果,聚合已完成。现在发布聚合我需要做另一个过滤器来获取一些文档,这些文档仅在包含 [] 中存在的一个字段中具有特定值。例如。聚合后,我得到了不同状态的文档:有些是,有些不是,我只需要那些是的。
  • @sox 请发布单独的问题以及相关详细信息。
猜你喜欢
  • 1970-01-01
  • 2019-07-12
  • 2021-02-11
  • 1970-01-01
  • 2014-03-24
  • 2015-01-23
  • 2016-04-12
  • 2022-01-26
  • 2017-10-26
相关资源
最近更新 更多