计算ElasticSearch中列表字段中的元素数

kcugc4gi  于 2022-12-11  发布在  ElasticSearch
关注(0)|答案(2)|浏览(156)

我还在学习如何在ElasticSearch中使用DSL查询。我有一些文档中的一个字段是列表。我需要计算这个字段中有一个元素、这个字段中有两个元素等的文档的数量。例如,下面是一个文档结构:
文件1:

"Volume": [
{
"partition": "s1",
"fieldtype": ["A","B"]
}
]

文件二:

"Volume": [
{
"partition": "s1",
"fieldtype": ["A"]
}
]

文件三:

"Volume": [
{
"partition": "s1",
"fieldtype": ["B"]
}
]

我需要一种方法来计算出有一个文档在fieldtype字段中有2个元素,有2个文档在fieldtype中有1个元素。如果我尝试将它们聚合为:

"size":0,
"aggs": {
"name": {
"terms": {
"field": "fieldtype.keyword"
}
}
}

我得到了元素的计数(A和B的数量)。如果不使用关键字,我会得到一个错误。

20jt8wwn

20jt8wwn1#

我设想您使用嵌套类型。下面是我的解决方案:

PUT idx_test
{
  "mappings": {
    "properties": {
      "Volume": {
        "type": "nested"
      }
    }
  }
}

POST idx_test/_bulk
{"index":{ "_id": 1}}
{"Volume":[{"partition": "s1","fieldtype": ["A","B"]}]}
{"index":{ "_id": 2}}
{"Volume":[{"partition": "s1","fieldtype": ["A"]}]}
{"index":{ "_id": 3}}
{"Volume":[{"partition": "s1","fieldtype": ["B"]}]}

GET idx_test/_search
{
  "size": 0,
  "aggs": {
    "doc_id": {
      "terms": {
        "field": "_id",
        "size": 10
      },
      "aggs": {
        "volumes": {
          "nested": {
            "path": "Volume"
          },
          "aggs": {
            "size": {
              "sum": {
                "script": {
                  "lang": "painless",
                  "source": "doc['Volume.fieldtype.keyword'].size()"
                }
              }
            }
          }
        }
      }
    }
  }
}

答复:

"aggregations" : {
    "doc_id" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "1",
          "doc_count" : 1,
          "volumes" : {
            "doc_count" : 1,
            "size" : {
              "value" : 2.0
            }
          }
        },
        {
          "key" : "2",
          "doc_count" : 1,
          "volumes" : {
            "doc_count" : 1,
            "size" : {
              "value" : 1.0
            }
          }
        },
        {
          "key" : "3",
          "doc_count" : 1,
          "volumes" : {
            "doc_count" : 1,
            "size" : {
              "value" : 1.0
            }
          }
        }
      ]
    }
  }
vx6bjr1n

vx6bjr1n2#

@rabbitbr提供了一个很好的答案,但是我不明白为什么我们要使用嵌套字段。而且,我认为我们需要在这里使用术语聚合而不是求和。不管怎样,这里有一个没有嵌套的解决方案:

PUT idx_test

POST idx_test/_bulk
{"index":{ "_id": 1}}
{"Volume":[{"partition": "s1","fieldtype": ["A","B"]}]}
{"index":{ "_id": 2}}
{"Volume":[{"partition": "s1","fieldtype": ["A"]}]}
{"index":{ "_id": 3}}
{"Volume":[{"partition": "s1","fieldtype": ["B"]}]}

GET idx_test/_mapping

GET idx_test/_search
{
  "size": 0,
  "aggs": {
    "size": {
      "terms": {
        "script": {
          "lang": "painless",
          "source": "doc['Volume.fieldtype.keyword'].size()"
        }
      }
    }
  }
}

如果不使用关键字,则会出现错误。
这是正常的,因为如果没有keyword,您会尝试在类型为text的字段上建立汇总。
下面是对上述查询的响应,这是一个非常基本的查询:

{
  ....
  "aggregations": {
    "size": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "1",
          "doc_count": 2
        },
        {
          "key": "2",
          "doc_count": 1
        }
      ]
    }
  }
}

如您所见,我们有2个文档具有1个大小的数组,还有1个文档具有2个大小的数组。

相关问题