聚合可以在elasticsearch中有两个键吗

Can an aggregation have two keys in elasticsearch

假设我有一个包含嵌套文档的索引,如下所示:

{
  "mappings": {
    "assignment": {
      "properties":{
        "id": {
        "type": "string"
      },
      "location": {
        "type": "string"
      },
      "typeOfLoss":{
        "type": "string"
      },
      "lineItems": {
        "type": "nested",
        "properties": {
          "categoryCode":{
            "type": "string"
          },
          "selectorCode":{
            "type": "string"
          },
          "roomType": {
            "type": "string"
          }
        }
}

我现在想要获取 "lineItems" 文档的计数聚合,其中 returns roomType 与搜索查询匹配的 selectorCode 和 categoryCode。我是 elasticsearch 的新手,可以在 SQL

中编写查询
SELECT COUNT(*) as theCount, ln.category_code, ln.selector_code
FROM line_items as ln, assignment
WHERE assignment.location = "84043"
AND assignment.typeOfLoss = "Fire"
AND ln.roomType = "kitchen"
GROUP BY ln.category_code, ln.selector_code
ORDER BY theCount DESC;

我已经开始进行 NEST 查询,但遇到了一些问题,希望有人能指出正确的方向。

var typeOfLossQuery = new TermQuery
{
  Field = "typeOfLoss",
  Value = typeOfLoss
};

var locationQuery = new TermQuery
{
  Field = "location",
  Value = location
};

var roomTypeQuery = new TermQuery
{
  Field = "roomType",
  Value = roomType
};

var result = client.Search<LineItem>(s => s
  .From(0)
  .Size(numberOfItems)
  .Query(q => q.HasParent<Assignment>(a => a
    .Query(x =>x
      .MatchAll() && typeOfLossQuery && locationQuery
    )
  ) && q.MatchAll() && roomTypeQuery
));

您确实可以使用 ElasticSearch 做到这一点,但它不像 SQL 中那样干净。我们可以用 Nested Aggregations.

来完成这个

设置

我将设置数据,以便您在 SQL 中获得以下等效结果:

类别代码 |选择器代码 |计数

c1 | s1 | 1

c1 | s2 | 2

PUT test1

PUT test1/_mapping/type1
{
  "properties": {
    "id": {
      "type": "string"
    },
    "location": {
      "type": "string"
    },
    "typeOfLoss": {
      "type": "string"
    },
    "lineItems": {
      "type": "nested",
      "properties": {
        "categoryCode": {
          "type": "string",
          "fielddata": true
        },
        "selectorCode": {
          "type": "string",
          "fielddata": true
        },
        "roomType": {
          "type": "string"
        }
      }
    }
  }
}

POST test1/type1
{
  "location":"l1",
  "lineItems":
    {
      "categoryCode": "c1",
      "selectorCode": "s1",
      "roomType": "r1"
    }
}

POST test1/type1
{
  "location":"l1",
  "lineItems":
    {
      "categoryCode": "c1",
      "selectorCode": "s2",
      "roomType": "r1"
    }
}

POST test1/type1
{
  "location":"l1",
  "lineItems":
    {
      "categoryCode": "c1",
      "selectorCode": "s2",
      "roomType": "r1"
    }
}

查询

GET test1/type1/_search
{
  "size": 0,
  "query": {
    "nested": {
      "path": "lineItems",
      "query": {
        "term": {
          "lineItems.roomType": {
            "value": "r1"
          }
        }
      }
    }
  },
  "aggs": {
    "nestedAgg": {
      "nested": {
        "path": "lineItems"
      },
      "aggs": {
        "byCategory": {
          "terms": {
            "field": "lineItems.categoryCode",
            "size": 10
          },
          "aggs": {
            "bySelector": {
              "terms": {
                "field": "lineItems.selectorCode",
                "size": 10
              }
            }
          }
        }
      }
    }
  }
}

我的查询内容如下:

  1. 只显示数据 where roomType = 'r1'

  2. 通过categoryCode

  3. 聚合(SQL中的组)
  4. 在 "selectorCode"

  5. 上创建了 "nested" 或 "sub" 聚合

结果

{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "nestedAgg": {
      "doc_count": 3,
      "byCategory": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "c1",
            "doc_count": 3,
            "bySelector": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": [
                {
                  "key": "s2",
                  "doc_count": 2
                },
                {
                  "key": "s1",
                  "doc_count": 1
                }
              ]
            }
          }
        ]
      }
    }
  }
}

所以结果 returns 聚合列表。聚合内部是一个 "bucket"。请注意,byCategory 的外层存储桶显示 doc_count 为 3。这是因为数据库中有 3 条记录匹配。

然后,嵌套在其中的 bySelector 桶显示 s2s1doc_count 分别为 2 和 1。

希望对您有所帮助,我会让您将所有这些变成一个 NEST 查询。