如何在Elasticsearch中将父字段值与嵌套对象中的聚合值进行比较?

时间:2019-03-14 14:00:31

标签: elasticsearch elasticsearch-aggregation elasticsearch-nested

我的索引中有这样的文件:

  {
    "Pieces": 5,
    "parts": [
      {
        "Quantity": 1,
        "PartID": 1,
      },
      {
        "Quantity": 1,
        "PartID": 2
      },
      {
        "Quantity": 1,
        "PartID": 3
      },
      {
        "Quantity": 1,
        "PartID": 4
      }
    ]
  }

我想准备一个查询,列出所有Pieces值不等于所有Quantityparts的总和的文档。我有这样的东西:

GET /_search
{
  "size": 0,
  "aggs": {
    "group_by_id": {
      "terms": {
        "field": "_id",
        "size": 1000000000
      },
      "aggs": {
        "sum_of_parts": {
          "nested": {
            "path": "parts"
          },
          "aggs": {
            "sum_of_quantity": {
              "sum": {
                "field": "parts.Quantity"
              }
            }
          }
        },
        "sum_of_parts_vs_pieces": {
          "bucket_selector": {
            "buckets_path": {
              "sumOfPart": "sum_of_parts>sum_of_quantity"
            },
            "script": "params.sumOfPart != HOW_TO_PUT_Pieces_VALUE_HERE???"
          }
        }
      }
    }
  }
}

几乎可以正常工作(计算所有部分的Quantity之和)...但是...我不知道如何将Pieces的值传递给bucket_selector

您知道如何执行此操作吗?或者,也许您对如何以另一种方式完成此任务有一个想法?

1 个答案:

答案 0 :(得分:2)

您可以通过添加Pieces字段的平均值来做到这一点(使用reverse_nested返回一级):

GET pieces/_search
{
  "size": 0,
  "aggs": {
    "group_by_id": {
      "terms": {
        "field": "_id",
        "size": 1000000000
      },
      "aggs": {
        "sum_of_parts": {
          "nested": {
            "path": "parts"
          },
          "aggs": {
            "avg_of_pieces": {
              "reverse_nested": {},
              "aggs": {
                "avg_of_pieces": {
                  "avg": {
                    "field": "Pieces"
                  }
                }
              }
            },
            "sum_of_quantity": {
              "sum": {
                "field": "parts.Quantity"
              }
            }
          }
        },
        "sum_of_parts_vs_pieces": {
          "bucket_selector": {
            "buckets_path": {
              "sumOfPart": "sum_of_parts>sum_of_quantity",
              "nbPieces": "sum_of_parts>avg_of_pieces>avg_of_pieces"
            },
            "script": "params.sumOfPart != params.nbPieces"
          }
        }
      }
    }
  }
}