Numeric が出るはずのbuckets_pathにおけるgot: [Object[]]エラーについて

お世話になります。質問させていただきます。
現在、aggsで出力された中央値を条件に使おうとしています。

サンプルクエリでは、中央値の出力までは出来ていますが、計算に使おうとすると、

"type": "aggregation_execution_exception",
      "reason": "buckets_path must reference either a number value or a single value numeric metric aggregation, got: [Object[]] at aggregation [10day]"

となります。
percentilesではなく、sumも試してみましたが、このエラーメッセージに変化はありませんでした。

そこで
・このエラーはなぜ起きているのか
・Objectが何なのか調べる方法はあるか
という質問となります。
ご協力いただけますと幸いです。

request

{
  "size": 0,
  "aggs": {
    "category": {
      "terms": {
        "field": "category_id",
        "size": 1
      },
      "aggs": {
        "10day": {
          "date_range": {
            "field": "end_at",
            "format": "yyyy-MM-dd HH:mm:ss",
            "ranges": [
              {
                "from": "now-10d",
                "to": "now"
              }
            ]
          },
          "aggs": {
            "median_price": {
              "percentiles": {
                "field": "end_price",
                "percents": [
                  50
                ]
              }
            }
          }
        },
        "30day": {
          "date_range": {
            "field": "end_at",
            "format": "yyyy-MM-dd HH:mm:ss",
            "ranges": [
              {
                "from": "now-30d",
                "to": "now"
              }
            ]
          },
          "aggs": {
            "median_price": {
              "percentiles": {
                "field": "end_price",
                "percents": [
                  50
                ]
              }
            }
          }
        },
        "calculation": {
          "bucket_script": {
            "buckets_path": {
              "a": "10day>median_price[50.0]",
              "b": "30day>median_price[50.0]"
            },
            "script":  "params.a / params.b"
          }
        },
        "return_filter": {
          "bucket_selector": {
            "buckets_path": {
              "increase_ratio": "calculation"
            },
            "script": "params.increase_ratio <= 1.3"
          }
        }
      }
    }
  }
}

response

{
  "error": {
    "root_cause": [],
    "type": "search_phase_execution_exception",
    "reason": "",
    "phase": "fetch",
    "grouped": true,
    "failed_shards": [],
    "caused_by": {
      "type": "aggregation_execution_exception",
      "reason": "buckets_path must reference either a number value or a single value numeric metric aggregation, got: [Object[]] at aggregation [10day]"
    }
  },
  "status": 500
}

中央値の例

{
  "took" : 10180,
  "timed_out" : false,
  "_shards" : {
    "total" : 40,
    "successful" : 40,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "category" : {
      "doc_count_error_upper_bound" : 451394,
      "sum_other_doc_count" : 197182706,
      "buckets" : [
        {
          "key" : 20068,
          "doc_count" : 950429,
          "10day" : {
            "buckets" : [
              {
                "key" : "2020-05-11 08:36:13-2020-05-21 08:36:13",
                "from" : 1.589186173556E12,
                "from_as_string" : "2020-05-11 08:36:13",
                "to" : 1.590050173556E12,
                "to_as_string" : "2020-05-21 08:36:13",
                "doc_count" : 19633,
                "median_price" : {
                  "values" : {
                    "50.0" : 800.0
                  }
                }
              }
            ]
          },
          "30day" : {
            "buckets" : [
              {
                "key" : "2020-04-21 08:36:13-2020-05-21 08:36:13",
                "from" : 1.587458173556E12,
                "from_as_string" : "2020-04-21 08:36:13",
                "to" : 1.590050173556E12,
                "to_as_string" : "2020-05-21 08:36:13",
                "doc_count" : 73913,
                "median_price" : {
                  "values" : {
                    "50.0" : 800.0
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

少しややこしいですよね、ログ。。。

このエラーメッセージは「10day」のところが配列で返ってきてる(got: [Object[]] at aggregation [10day])ので、buckets_pathどれを指しているのかがわからないので、1つの値を取るように指定してくれということです。

実際、data_rangerangesが配列なので、複数返る可能性があるaggregationになっています。

解決策としては、10dayのところのどの値なのかを知らせてやれば解決します。

解決案としては2つあって、

  1. date_rangeのバケットに名前をつけて、名前でbuckets_pathの指定を行う
  2. date_rangeの代わりにfilter+rangeクエリで1つのbucketが返るようにする

って感じでしょうか。

1の名前を付ける方法はKeyed Responseです。keyを指定しない場合は、日付の文字列が返ってきてしまいますが、動かしている時間によって、文字が変わってしまいます。なので、toの行の後に、"key": "hoge"のように戻ってくるバケットに名前をつけて、buckets_path10day["hoge"]のように指定する方法です。

2の案はfilter aggregationあたりを参考にやってみてください。

1 Like

素早いお返事、ありがとうございます。
ご指摘の改善点で問題が解決しました。そういうことなのですね。

現状、1.3の変動を持つものを抽出する
return_filter
が動作していませんが、
もしよろしければこちらも動作させるのに参考のページはありますでしょうか?

{
  "size": 0,
  "aggs": {
    "category": {
      "terms": {
        "field": "category_id",
        "size": 1
      },
      "aggs": {
        "10day": {
          "filter": {
            "range": {
              "end_at": {
                "format": "yyyy-MM-dd HH:mm:ss",
                "gte": "now-10d/d",
                "lte": "now/d"
              }
            }
          },
          "aggs": {
            "median_price": {
              "percentiles": {
                "field": "end_price",
                "percents": [
                  50
                ]
              }
            }
          }
        },
        "30day": {
          "filter": {
            "range": {
              "end_at": {
                "format": "yyyy-MM-dd HH:mm:ss",
                "gte": "now-30d/d",
                "lte": "now/d"
              }
            }
          },
          "aggs": {
            "median_price": {
              "percentiles": {
                "field": "end_price",
                "percents": [
                  50
                ]
              }
            }
          }
        },
        "calculation": {
          "bucket_script": {
            "buckets_path": {
              "a": "10day>median_price[50.0]",
              "b": "30day>median_price[50.0]"
            },
            "script":  "params.a / params.b"
          }
        },
        "return_filter": {
          "bucket_selector": {
            "buckets_path": {
              "increase_ratio": "calculation"
            },
            "script": "params.increase_ratio <= 1.3"
          }
        }
      }
    }
  }
}
{
  "took" : 6678,
  "timed_out" : false,
  "_shards" : {
    "total" : 40,
    "successful" : 40,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "category" : {
      "meta" : { },
      "doc_count_error_upper_bound" : 451718,
      "sum_other_doc_count" : 197354248,
      "buckets" : [
        {
          "key" : 20068,
          "doc_count" : 951932,
          "10day" : {
            "meta" : { },
            "doc_count" : 21364,
            "median_price" : {
              "values" : {
                "50.0" : 800.0
              }
            }
          },
          "30day" : {
            "meta" : { },
            "doc_count" : 75620,
            "median_price" : {
              "values" : {
                "50.0" : 800.0
              }
            }
          },
          "calculation" : {
            "value" : 1.0
          }
        }
      ]
    }
  }
}

1.3以上のものを返したいのであれば、条件が逆向きですね。
参考 : https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-selector-aggregation.html

1 Like

すいません、ありがとうございます。
トライアンドエラーの一つのコードを張り、大変間の抜けた質問になってしまいました。
実際お尋ねしたかったのは
numeric的なものが返ってくるはずが、返ってくるはずがない(null)ような値が返ってきて起こした話で、以下のようになります。
こちらも参考になるドキュメントの箇所などお教えいただけますと幸いです。

大部分は同一で、sizeを2にしたものを実行すると・・・

{
  "size": 0,
  "aggs": {
    "category": {
      "terms": {
        "field": "category_id", //int等ではなく、文字列です
        "size": 2
      },

中央値でnullが返ってくるkey:23316が取得できました。
これだけですと期間内にデータが無いのかなと思ってしまいますが・・・

        ...
        {
          "key" : 23316,
          "doc_count" : 815619,
          "10day" : {
            "meta" : { },
            "doc_count" : 0,
            "median_price" : {
              "values" : {
                "50.0" : null
              }
            }
          },
          "30day" : {
            "meta" : { },
            "doc_count" : 0,
            "median_price" : {
              "values" : {
                "50.0" : null
              }
            }
          }
        }

23316を指定したbool mustを追加してやると・・・

"query" : {
    "bool":{
      "must":[
        {
          "match" : 
          {
            "category_id" : "23316"
          }
        }
      ]
    }
  },
  "aggs": {
    "category": {
      "terms": {
        "field": "category_id",
        "size": 2
      },

ちゃんと、中央値が出てきます。

{
          "key" : 23316,
          "doc_count" : 842259,
          "10day" : {
            "meta" : { },
            "doc_count" : 4099,
            "median_price" : {
              "values" : {
                "50.0" : 1199.2535940195514
              }
            }
          },
          "30day" : {
            "meta" : { },
            "doc_count" : 16233,
            "median_price" : {
              "values" : {
                "50.0" : 1301.5371428571432
              }
            }
          },
          "calculation" : {
            "value" : 0.9214132693800361
          }
        }

termsの理解が出来ていないのだとは思いますが
イメージと異なる動作で戸惑っております・・・

追記です。怪しいのはこのあたりかなとは思います。

中央値が出ないもの

      "doc_count_error_upper_bound" : 422594,
      "sum_other_doc_count" : 196593107,

中央値が出るもの

      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,

このスレッドが参考になるかもしれないです。

1 Like

無事意図したものが返ってきました。

また落ち着いたらどこかでお会いさせてください。
どうもありがとうございました。

1 Like