Группировка с Elasticsearch (aggs) для объединения поля в список значений - PullRequest
0 голосов
/ 09 мая 2018

У меня есть индекс с несколькими типами. Данные в каждой записи включают такие поля, как «Идентификатор клиента» и «Имя устройства», «URL» и т. Д.

Elasticsearch v5.6.8.

То, что я хотел бы закончить, это один документ на «Идентификатор клиента» и «Имя устройства» и значение _type для документа. Один документ для каждой группы должен иметь список значений 'url', объединенных в одно поле с именем 'urls'.

Я попробовал следующее, но это не сработало так, как я думал, и я не уверен, что еще попробовать:

GET _search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "_index": "safebrowsing"
          }
        },
        {
          "range": {
            "eventtime": {
              "gte": "now-5d/d"
            }
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "reported_to_client": true
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "Customer ID": {
      "terms": {
        "field": "Customer ID.keyword"
      },
      "aggs": {
        "Device Name": {
          "terms": {
            "field": "Device Name.keyword"
          },
          "aggs": {
            "documenttype": {
              "terms": {
                "field": "_type"
              },
              "aggs": {
                "urls": {
                  "terms": {
                    "script": "_doc['url'].values"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Это ошибка, которую я получаю:

{
  "error": {
    "root_cause": [
      {
        "type": "circuit_breaking_exception",
        "reason": "[script] Too many dynamic script compilations within one minute, max: [15/min]; please use on-disk, indexed, or scripts with parameters instead; this limit can be changed by the [script.max_compilations_per_minute] setting",
        "bytes_wanted": 0,
        "bytes_limit": 0
      },
      {
        "type": "script_exception",
        "reason": "compile error",
        "script_stack": [
          "_doc['url'].values",
          "^---- HERE"
        ],
        "script": "_doc['url'].values",
        "lang": "painless"
      }
    ],
...etc

1 Ответ

0 голосов
/ 11 мая 2018

Я понял это ... По сути, нужно иметь тип агрегации top_hits, который возвращает фактические попадания (столько, сколько указано "size") в каждой агрегации более высокого уровня.

GET /_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {"_index": "safebrowsing"}},
        {"range": {"eventtime": {"gte": "now-2d/d"}}}
      ],
      "must_not": [
        {"term": {"reported_to_client": true}}
      ]
    }
  },
  "aggs": {
    "Customer ID": {
      "terms": {
        "field": "Customer ID.keyword"
      },
      "aggs": {
        "Device Name": {
          "terms": {
            "field": "Device Name.keyword"
          },
          "aggs": {
            "thetype": {
              "terms": {
                "field": "_type"
              },
              "aggs": {
                "thedocs": {
                  "top_hits": {
                    "sort": [{"eventtime": {"order": "desc"}}],
                    "_source": {
                      "includes": [ "ip", "type", "eventtime", "url" ]
                    },
                    "size": 2
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "size": 0
}

Каждый удар в агрегате, который я назвал thedocs, выглядит следующим образом:

{
  "_index": "safebrowsing",
  "_type": "SOCIAL_ENGINEERING",
  "_id": "7ffe641xxxyyydc3536189ce33d5dfb9",
  "_score": null,
  "_source": {
    "ip": "xxx.xxx.7.88",
    "eventtime": "2018-05-08T23:34:03-07:00",
    "type": "SOCIAL_ENGINEERING",
    "url": "http://xyz-domainname.tld/bankofwhatever/"
  },
  "sort": [
    1525847643000
  ]
}
...