Search code examples
elasticsearchkibanaelastic-stackelkelasticsearch-painless

Kibana painless script to count the json list size


I have the json data in the elasticsearch index as below:

{
  "_index": "tower",
  "_type": "_doc",
  "_id": "sadssasadsadsa",
  "_version": 1,
  "_score": null,
  "_source": {
    "task": "",
    "event_data": {
      "playbook_uuid": "sasdsad21w",
      "processed": {
        "11.22.33.46": 1,
        "11.22.33.44": 1,
        "11.22.33.45": 1
      },
      "failures": {
        "11.22.33.46": 1
      },
      "changed": {
        "11.22.33.44": 1
      },
      "playbook": "test.yml",
      "ignored": {},
      "ok": {
        "11.22.33.46": 1,
        "11.22.33.44": 4,
        "11.22.33.45": 1
      },
      "dark": {
        "11.22.33.45": 1
      }
    },
    "level": "INFO",
    "event_display": "Playbook Complete",
    "stdout": "\r\nPLAY RECAP *********************************************************************\r\n\u001b[0;33m11.22.33.44\u001b[0m               : \u001b[0;32mok=4   \u001b[0m \u001b[0;33mchanged=1   \u001b[0m unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   \r\n\u001b[0;31m11.22.33.45\u001b[0m               : \u001b[0;32mok=1   \u001b[0m changed=0    \u001b[1;31munreachable=1   \u001b[0m failed=0    skipped=0    rescued=0    ignored=0   \r\n\u001b[0;31m11.22.33.46\u001b[0m              : \u001b[0;32mok=1   \u001b[0m changed=0    unreachable=0    \u001b[0;31mfailed=1   \u001b[0m skipped=0    rescued=0    ignored=0   \r\n",
    "@version": "1",
    "tags": [
      "tower"
    ]
  },
  "fields": {
    "@timestamp": [
      "2020-12-24T06:14:20.202Z"
    ]
  }
}

Now i want to create a painless script which will count the size of

"processed": {
        "11.22.33.46": 1,
        "11.22.33.44": 1,
        "11.22.33.45": 1
},
"failures": {
        "11.22.33.46": 1
},
"dark": {
        "11.22.33.45": 1
}

For example, here the count will look something like

processed: 3
failures: 1
dark: 1

All these values will be stores in a new field.

I tried using return params['_source']['event_data']['processed'].size(); just to get the processed size but it does not work.

Any help would be appreciated.


Solution

  • You can use script_fields like so:

    GET tower/_search
    {
      "script_fields": {
        "ev_data_counts": {
          "script": {
            "source": """
              def counts_by_status = [:];
              counts_by_status['processed'] = params['_source']['event_data']['processed'].size();
              counts_by_status['failures'] = params['_source']['event_data']['failures'].size();
              counts_by_status['dark'] = params['_source']['event_data']['dark'].size();
              return counts_by_status
            """
          }
        }
      }
    }
    

    yielding

    "hits" : [
      {
        ...
        "fields" : {
          "ev_data_counts" : [
            {
              "processed" : 3,
              "failures" : 1,
              "dark" : 1
            }
          ]
        }
      }
    ]