【问题标题】:How to count number of fields inside nested field? - Elasticsearch如何计算嵌套字段中的字段数? - 弹性搜索
【发布时间】:2020-09-08 04:07:01
【问题描述】:

我做了以下映射。我想计算每个嵌套字段“产品”中的产品数量(分别针对每个文档)。我还想做一个直方图聚合,这样我就可以知道特定桶大小的数量。

PUT /receipts
{
  "mappings": {
    "properties": {
      "id" : {
        "type": "integer"
      },
      "user_id" : {
        "type": "integer"
      },
      "date" : {
        "type": "date"
      },
      "sum" : {
        "type": "double"
      },
    "products" : {
      "type": "nested",
      "properties": {
        "name" : {
          "type" : "text"
        },
        "number" : {
          "type" : "double"
        },
        "price_single" : {
          "type" : "double"
        },
        "price_total" : {
          "type" : "double"
        }
      }
    }
}
}
}

我试过这个查询,但我得到的是所有产品的数量,而不是每个文档的产品数量。

GET /receipts/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "terms": {
      "nested": {
        "path": "products"
      },
      "aggs": {
        "bucket_size": {
          "value_count": {
            "field": "products"
          }
        }
      }
    }
  }
}

查询结果:

"aggregations" : {
    "terms" : {
      "doc_count" : 6552,
      "bucket_size" : {
        "value" : 0
      }
    }
  }

更新

现在我有了这段代码,我在其中为每个 id 制作单独的存储桶并计算其中的产品数量。

GET /receipts/_search
{
  "query": {
    "match_all": {}
  },
  "size" : 0,
  "aggs": {
    "terms":{
      "terms":{
        "field": "_id"
      },
      "aggs": {
        "nested": {
          "nested": {
            "path": "products"
          },
          "aggs": {
            "bucket_size": {
              "value_count": {
                "field": "products.number"
              }
            }
          }
        }
      }
    }
  }
}

查询结果:

"aggregations" : {
    "terms" : {
      "doc_count_error_upper_bound" : 5,
      "sum_other_doc_count" : 490,
      "buckets" : [
        {
          "key" : "1",
          "doc_count" : 1,
          "nested" : {
            "doc_count" : 21,
            "bucket_size" : {
              "value" : 21
            }
          }
        },
        {
          "key" : "10",
          "doc_count" : 1,
          "nested" : {
            "doc_count" : 5,
            "bucket_size" : {
              "value" : 5
            }
          }
        },
        {
          "key" : "100",
          "doc_count" : 1,
          "nested" : {
            "doc_count" : 12,
            "bucket_size" : {
              "value" : 12
            }
          }
        },
...

是否可以将这些值 (21, 5, 12, ...) 分组到桶中以制作它们的直方图?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    products 只是单个产品数组的路径,而不是可聚合 字段。所以你需要在你的产品的一个领域使用它——比如number:

    GET receipts/_search
    {
      "size": 0,
      "aggs": {
        "terms": {
          "nested": {
            "path": "products"
          },
          "aggs": {
            "bucket_size": {
              "value_count": {
                "field": "products.number"
              }
            }
          }
        }
      }
    }
    

    请注意,如果产品没有number,它不会计入总数。因此,最佳做法是始终在每个字段中包含一个 ID,然后在该字段上进行聚合。

    或者,您可以使用a script 来解释缺失值。幸运的是 value_count 不会进行重复数据删除——这意味着如果两个产品相似和/或具有空值,它们仍将被计为两个:

    GET receipts/_search
    {
      "size": 0,
      "aggs": {
        "terms": {
          "nested": {
            "path": "products"
          },
          "aggs": {
            "bucket_size": {
              "value_count": {
                "script": {
                  "source": "doc['products.number'].toString()"
                }
              }
            }
          }
        }
      }
    }
    

    更新

    您还可以使用嵌套复合聚合,它会为您提供带有相应收据 ID 的直方图产品计数:

    GET /receipts/_search
    {
      "size": 0,
      "aggs": {
        "my_aggs": {
          "nested": {
            "path": "products"
          },
          "aggs": {
            "composite_parent": {
              "composite": {
                "sources": [
                  {
                    "receipt_id": {
                      "terms": {
                        "field": "_id"
                      }
                    }
                  },
                  {
                    "product_number": {
                      "histogram": {
                        "field": "products.number",
                        "interval": 1
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }
    

    interval 是可修改的。

    【讨论】:

    • 在这两种情况下我都会得到这个结果:"aggregations" : { "terms" : { "doc_count" : 6552, "bucket_size" : { "value" : 6552 } } } 但我想获得第一个文档、第二个文档、第三个文档等的产品数量。
    • 单独还是合计?另外,您有多少顶级文档? GET receipts/_search?track_total_hits=true
    • { "took" : 2, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 500, "relation" : "eq" }, "max_score" : 1.0, "hits" : [...] 我想分别获取 500 笔交易中每笔交易的产品数量,以便能够将其放在直方图上。我不知道这是否可能,因为我是新手。
    • 我明白了。所以最后你想要一个包含所有相应收据的每个产品的单独直方图?或者更确切地说,是在给定收据内购买的所有产品的每张收据直方图?因为给定收据下的所有产品共享相同的日期,不会带来太多价值。请澄清。
    • 最后,我想要一个显示给定数量产品频率的直方图。我更新了我的问题,现在我有了产品的数量,但我很好奇是否有办法将它们分组到桶中以制作直方图。
    猜你喜欢
    • 2021-01-21
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 1970-01-01
    相关资源
    最近更新 更多