ElasticSearch:嵌套聚合但获取根doc_count

时间:2016-10-15 07:19:41

标签: elasticsearch

我使用ElasticSearch索引某些用户属性,用户数据mondel如下所示,fxy是在gx组下组合在一起的一组属性

User: {
  g1: {
    f11: ...,
    f12: ...,
    f13: ...
  },
  g2: {
    f21: ...,
    f22: ...,
    f23: ...
  }
}

所以我可以通过使用嵌套聚合

获得f11的前N个结果
{
  "query": {
    ...
  },
  "aggs": {
    "l1": {
      "nested": {
        "path": "g1"
      },
      "aggs": {
        "l2": {
          "terms": {
            "field": "g1.f11"
          }
        }
      }
    }
  }
}

并且响应就像

{
  "aggregations": {
    "l1": {
      "doc_count": .....,
      "l2": {
        "buckets": [
          {
            "key": k1,
            "doc_count": ...
          },
          {
            "key": k2,
            "doc_count": ...
          }
          ...
        ]
      }
    }
  }
}

我的问题是嵌套聚合中的所有doc_count都是gxfxy=kz的数字。有没有办法让至少有一个gx的用户满意fxy=kz

2 个答案:

答案 0 :(得分:0)

目前我们的解决方法是

  • 将嵌套对象中的数据复制到根级对象
  • 首先使用嵌套聚合
  • 查询f11的前N个结果
  • 将前N个结果作为查询过滤器的一部分应用,然后在第一级字段上汇总。

这意味着

将映射更改为

User: {
  g1_f11: [],
  g1_f12: [],
  ...
  g2_f21: [],
  g2_f22: [],
  ...,
  g1: {
    f11: ...,
    f12: ...,
    f13: ...
  },
  g2: {
    f21: ...,
    f22: ...,
    f23: ...
  }
}

获取字段f11的前N个结果,然后作为过滤器的一部分应用,并在g1_f11上汇总

{
  "query": {
    "nested": {
      "path": "g1",
      "query": {
        "should": [
          {
            "match": {
              "g1" {
                "query": "k1"
              }              
            }
          },
          {
            "match": {
              "g1" {
                "query": "k2"
              }              
            }
          },
          ...
        ]
      }
    }
  },
  "aggs": {
    "l1": {
      "terms": {
        "fields": "g1_f11"
      }
    }
  }
}

然后聚合输出中的最终doc_count将是用户数

答案 1 :(得分:0)

发现事实证明ElasticSearch确实提供了解决方案:reverse nested aggregation。这正是我们想要的。