Повторная агрегация вложенных результатов агрегации с использованием Elasticsearch - PullRequest
0 голосов
/ 01 апреля 2019

Я хочу вычислить некоторые агрегации (используя Elasticsearch 6.2) для продуктов, которые имеют критерии.Все критерии сведены, и я хочу повторно использовать некоторые результаты агрегирования для повторной агрегации по определенному критерию.

Вот мое отображение индекса:

PUT my_index
{
  "mappings" : {
    "_doc" : {
      "properties" : {

        "contract": {
          "properties": {

            "products": {
              "type": "nested",
              "properties": {
                "productKey": {
                  "type": "keyword"
                },

                "criteria": {
                  "type": "nested",
                  "properties": {
                    "criterionKey": {
                      "type": "keyword"
                    },
                    "criterionValue": {
                      "type": "keyword"
                    }
                  }
                }

              }
            }

          }
        }

      }
    }
  }
}

Я заполнил свой индекс следующими данными:

POST my_index/_doc
{

  "contract": {
    "products": [
      {
        "productKey": "PK_0001",
        "criteria": [
          {
            "criterionKey": "CK_AAAA",
            "criterionValue": "above_50"
          },
          {
            "criterionKey": "CK_AAAB",
            "criterionValue": "all"
          }
        ]
      }
    ]
  }
}

POST my_index/_doc
{

  "contract": {
    "products": [
      {
        "productKey": "PK_0001",
        "criteria": [
          {
            "criterionKey": "CK_AAAA",
            "criterionValue": "below_50"
          },
          {
            "criterionKey": "CK_AAAB",
            "criterionValue": "dep"
          }
        ]
      }
    ]
  }
}

POST my_index/_doc
{

  "contract": {
    "products": [
      {
        "productKey": "PK_0002",
        "criteria": [
          {
            "criterionKey": "CK_AAAA",
            "criterionValue": "below_50"
          },
          {
            "criterionKey": "CK_AAAB",
            "criterionValue": "dep"
          }
        ]
      }
    ]
  }
}

Я могу подсчитать вхождения всех значений критериев для каждого продукта.Для этого я использую следующий запрос агрегации:

POST my_index/_doc/_search
{
  "size": 0,
  "aggs": {
    "agg_by_product": {
      "nested": {
        "path": "contract.products"
      },
      "aggs": {
        "agg_by_product_key": {
          "terms": {
            "field": "contract.products.productKey"
          },
          "aggs": {
            "agg_by_product_crit": {
              "nested": {
                "path": "contract.products.criteria"
              },
              "aggs": {
                "agg_by_product_crit_key": {
                  "terms": {
                    "field": "contract.products.criteria.criterionKey",
                    "include": [ "CK_AAAB", "CK_AAAA" ]
                  },
                  "aggs": {
                    "agg_by_product_crit_value": {
                      "terms": {
                        "field": "contract.products.criteria.criterionValue"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Возвращает:

{
  // ...
  "aggregations": {
    "agg_by_product": {
      "doc_count": 3,
      "agg_by_product_key": {
        "buckets": [
          {
            "key": "PK_0001",
            "doc_count": 2,
            "agg_by_product_crit": {
              "doc_count": 8,
              "agg_by_product_crit_key": {
                "buckets": [
                  {
                    "key": "CK_AAAB",
                    "doc_count": 2,
                    "agg_by_product_crit_value": {
                      "buckets": [
                        {
                          "key": "dep",
                          "doc_count": 1
                        },
                        {
                          "key": "all",
                          "doc_count": 1
                        }
                      ]
                    }
                  },
                  {
                    "key": "CK_AAAA",
                    "doc_count": 2,
                    "agg_by_product_crit_value": {
                      "buckets": [
                        {
                          "key": "below_50",
                          "doc_count": 1
                        },
                        {
                          "key": "above_50",
                          "doc_count": 1
                        }
                      ]
                    }
                  }
                ]
              }
            }
          },
          {
            "key": "PK_0002",
            "doc_count": 1,
            "agg_by_product_crit": {
              "doc_count": 4,
              "agg_by_product_crit_key": {
                "buckets": [
                  {
                    "key": "CK_AAAB",
                    "doc_count": 1,
                    "agg_by_product_crit_value": {
                      "buckets": [
                        {
                          "key": "dep",
                          "doc_count": 1
                        }
                      ]
                    }
                  },
                  {
                    "key": "CK_AAAA",
                    "doc_count": 1,
                    "agg_by_product_crit_value": {
                      "buckets": [
                        {
                          "key": "below_50",
                          "doc_count": 1
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
}

Теперь Я хочу агрегировать по значениям критерия указанного ключа критерия , чтобы получить что-то вроде этого:

{
  // ...
  "aggregations": {
    "agg_by_product": {
      "doc_count": 3,
      "agg_by_product_key": {
        "buckets": [
          {
            "key": "PK_0001",
            "doc_count": 2,
            "agg_by_product_crit": {
              "doc_count": 8,
              "agg_by_product_crit_key": {
                "buckets": [
                  {
                    "key": "CK_AAAB",
                    "doc_count": 2,
                    "agg_by_product_crit_value": {
                      "buckets": [
                        {
                          "key": "dep",
                          "doc_count": 1,
                          "AGG_BY_SOMETHING": {
                            "buckets": [
                              {
                                "key": "CK_AAAA",
                                "doc_count": 1,
                                "AGG_BY_SOMETHING_2": {
                                  "buckets": [
                                    {
                                      "key": "below_50",
                                      "doc_count": 1
                                    }
                                  ]
                                }
                              }
                            ]
                          }
                        },
                        {
                          "key": "all",
                          "doc_count": 1,
                          "AGG_BY_SOMETHING": {
                            "buckets": [
                              {
                                "key": "CK_AAAA",
                                "doc_count": 1,
                                "AGG_BY_SOMETHING_2": {
                                  "buckets": [
                                    {
                                      "key": "above_50",
                                      "doc_count": 1
                                    }
                                  ]
                                }
                              }
                            ]
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            }
          },
          {
            "key": "PK_0002",
            "doc_count": 1,
            "agg_by_product_crit": {
              "doc_count": 4,
              "agg_by_product_crit_key": {
                "buckets": [
                  {
                    "key": "CK_AAAB",
                    "doc_count": 1,
                    "agg_by_product_crit_value": {
                      "buckets": [
                        {
                          "key": "dep",
                          "doc_count": 1,
                          "AGG_BY_SOMETHING": {
                            "buckets": [
                              {
                                "key": "CK_AAAA",
                                "doc_count": 1,
                                "AGG_BY_SOMETHING_2": {
                                  "buckets": [
                                    {
                                      "key": "below_50",
                                      "doc_count": 1
                                    }
                                  ]
                                }
                              }
                            ]
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
}

Каким должен быть соответствующий запрос агрегации?

1 Ответ

0 голосов
/ 02 апреля 2019

Наконец я нашел решение с использованием агрегации reverse_nested.

POST my_index/_doc/_search
{
  "size": 0,
  "aggs": {
    "agg_by_product": {
      "nested": {
        "path": "contract.products"
      },
      "aggs": {
        "agg_by_product_key": {
          "terms": {
            "field": "contract.products.productKey"
          },
          "aggs": {
            "agg_by_product_crit": {
              "nested": {
                "path": "contract.products.criteria"
              },
              "aggs": {
                "agg_by_product_crit_key": {
                  "terms": {
                    "field": "contract.products.criteria.criterionKey",
                    "include": [ "CK_AAAB" ]
                  },
                  "aggs": {
                    "agg_by_product_crit_value": {
                      "terms": {
                        "field": "contract.products.criteria.criterionValue"
                      },
                      "aggs": {
                        "agg_back_to_root": {
                          "reverse_nested": {},
                          "aggs": {
                            "agg_by_product_crit2": {
                              "nested": {
                                "path": "contract.products.criteria"
                              },
                              "aggs": {
                                "agg_by_product_crit_key2": {
                                  "terms": {
                                    "field": "contract.products.criteria.criterionKey",
                                    "include": [ "CK_AAAA" ]
                                  },
                                  "aggs": {
                                    "agg_by_product_crit_value2": {
                                      "terms": {
                                        "field": "contract.products.criteria.criterionValue"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
...