代码之家  ›  专栏  ›  技术社区  ›  JP Lew

如何根据术语聚合的嵌套文档计数对存储桶进行排序?

  •  0
  • JP Lew  · 技术社区  · 7 年前

    我有一个索引, invoices ,我需要将其聚合到每年的桶中,然后进行排序。

    我已经成功地使用Bucket Sort通过简单的和值对我的Bucket进行排序( revenue tax ).然而,我很难按照嵌套更深的doc_计数值进行排序( status ).

    我想订购我的水桶,而不仅仅是 收入 ,但也取决于 地位 等于1、2、3等的字段。。。

    我的索引中的文档如下所示:

    "_source": {
      "created_at": "2018-07-07T03:11:34.327Z",
      "status": 3,
      "revenue": 68.474,
      "tax": 6.85,
    }
    

    我要求我的聚合如下:

    const params = {
      index: 'invoices',
      size: 0,
      body: {
        aggs: {
          sales: {
            date_histogram: {
              field: 'created_at',
              interval: 'year',
            },
            aggs: {
              total_revenue: { sum: { field: 'revenue' } },
              total_tax: { sum: { field: 'tax' } },
              statuses: {
                terms: {
                  field: 'status',
                },
              },
              sales_bucket_sort: {
                bucket_sort: {
                  sort: [{ total_revenue: { order: 'desc' } }],
                },
              },
            },
          },
        },
      },
    }
    

    响应(被截断)如下所示:

    "aggregations": {
        "sales": {
            "buckets": [
                {
                    "key_as_string": "2016-01-01T00:00:00.000Z",
                    "key": 1451606400000,
                    "doc_count": 254,
                    "total_tax": {
                        "value": 735.53
                    },
                    "statuses": {
                        "sum_other_doc_count": 0,
                        "buckets": [
                            {
                                "key": 2,
                                "doc_count": 59
                            },
                            {
                                "key": 1,
                                "doc_count": 58
                            },
                            {
                                "key": 5,
                                "doc_count": 57
                            },
                            {
                                "key": 3,
                                "doc_count": 40
                            },
                            {
                                "key": 4,
                                "doc_count": 40
                            }
                        ]
                    },
                    "total_revenue": {
                        "value": 7355.376005351543
                    }
                },
              ]
            }
          }
    

    我想分类 key: 1 例如根据状态值为1的文档数量最多的存储桶进行订购。我尝试对术语聚合进行排序,然后像这样指定所需的键:

              statuses: {
                terms: {
                  field: 'status',
                  order: { _key: 'asc' },
                },
              },
              sales_bucket_sort: {
                bucket_sort: {
                  sort: [{ 'statuses.buckets[0]._doc_count': { order: 'desc' } }],
                },
              },
    

    然而,这并不奏效。它没有出错,只是似乎没有任何效果。

    许多年前,我注意到SO上的其他人也有类似的问题,但我希望从那时起出现一个更好的答案: Elasticsearch aggregation. Order by nested bucket doc_count

    谢谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   JP Lew    7 年前

    没关系,我知道了。我添加了一个单独的过滤器聚合,如下所示:

            aggs: {
              total_revamnt: { sum: { field: 'revamnt' } },
              total_purchamnt: { sum: { field: 'purchamnt' } },
              approved_invoices: {
                filter: {
                  term: {
                    status: 1,
                  },
                },
              },
    

    然后我可以像这样对值进行桶排序:

              sales_bucket_sort: {
                bucket_sort: {
                    sort: [{ 'approved_invoices>_count': { order: 'asc' } }],
                },
              },
    
        2
  •  0
  •   ShengHow95    4 年前

    以防有人再次提到这个问题。Elasticsearch 7.10版的最新更新可以通过以下方式运行:

          sales_bucket_sort: {
            bucket_sort: {
                sort: [{ '_count': { order: 'asc' } }],
            },
          }
    

    只有 _count 如果指定,它将自动采取 doc_count 并据此进行排序。