Query DSL to return multiple values in Sense / Watcher Reports


(Seth S) #1

Hey ES Wizards,

E.S. version 2.4.1

I am writing alarms and reports. I need to return multiple values from one Query DSL or wrap them somehow in order to pass both values into a report. Specifically, if I'm looking for Nginx Responses of "MISS" or "EXPIRED" (including the quotes), but I can't conglomerate the results, instead, I need the report to format as such:

Expires: {{payload.hits.total}} //only expires
Misses: {{payload.hits.total}} //only misses

Is this possible in one DSL Query? Is there a way I can nest them and alias the results so as to retrieve them in my report?

I can currently retrieve either misses or expires using:

GET /_search
{
"query": {
    "template": {
        "inline": { "match": { "NginxResponse": "{{query_string}}" }},
        "params" : {
            "query_string" : "\"EXPIRED\"",
            "filter": {
              "range": {
                "@timestamp": {
                  "from": "now-7d"
                }
              }
            }
        }
     }
  }
}

Which returns:

{
"took": 25,
"timed_out": false,
"_shards": {
  "total": 256,
  "successful": 256,
  "failed": 0
},
"hits": {
  "total": 1198037,
  "max_score": 7.3903913,
  "hits": [.......

I can get the result from this and reference it in my reports as
{{payload.hits.total}}<!code>

From the code in my report shown as:

    "input": {
  "search": {
    "request": {
      "indices": [
        "filebeat-*"
      ],
      "body": {
        "query": {
          "template": {
            "inline": {
              "match": {
                "NginxResponse": "{{query_string}}"
              }
            },
            "params": {
              "query_string": "\"MISS\"",
              "filter": {
                "range": {
                  "@timestamp": {
                    "from": "now-7d"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
},
"condition": {
  "script": {
    "script": "payload.hits.total > 100"
  }
}

Is there a way to modify this query so that I can pass in multiple variables that can be referenced in my report? This solution will also extend towards alarms that I'll generate once reporting is figured out.

Thanks in advance!

Edit: I may be barking up the wrong tree with the Query DSL, as I'm watching the Q&A following the 'Elasticsearch Query DSL' video and seeing that the Multi Search API https://www.elastic.co/guide/en/elasticsearch/reference/2.4/search-multi-search.html may be a better solution.

Does anyone have any solution architecture or best-approach suggestions? What I want to end up rolling up into the same report are three things; Misses, Expires & the ratio (Misses / (Misses + Expires)).


(Seth S) #2

So after familiarizing myself further with the architecture, I've got farther but still haven't cracked this issue yet.

I'm trying to access two things -- the hits for each 'NginxResponse', and the Bytes for each.

My query, which I can put into my report (minus the 'GET _search' part);

GET _search
{
  "size": 0,
  "query": {
"filtered": {
  "query": {
    "query_string": {
      "query": "*",
      "analyze_wildcard": true
    }
  },
  "filter": {
    "bool": {
      "must": [
        {
          "range": {
            "@timestamp": {
              "from": "now-7d"
            }
          }
        }
      ],
      "must_not": []
    }
  }
    }
      },
      "aggs": {
"2": {
  "terms": {
    "field": "NginxResponse",
    "size": 5,
    "order": {
      "_term": "desc"
    }
    },
  "aggs": {
    "1": {
      "sum": {
        "field": "Bytes"
      }
    }
  }
    }
  }
}

Which returns the results I'm looking for, however I'm unsure of how to access them from watcher (highlighted values are the bytes (seen as value: 'bytes') I'm trying to return for each 'bucket', which is the 'NginxResponse';

{
  "took": 4522,
  "timed_out": false,
  "_shards": {
    "total": 255,
    "successful": 255,
    "failed": 0
  },
  "hits": {
    "total": 256558336,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "2": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "1": {
            "value": 332866600316
          },
          "key": "\"MISS\"",
          "doc_count": 5531186
        },
        {
          "1": {
            "value": 3719896417498
          },
          "key": "\"HIT\"",
          "doc_count": 39592613
        },
        {
          "1": {
            "value": 24001020958
          },
          "key": "\"EXPIRED\"",
          "doc_count": 1995988
        },
        {
          "1": {
            "value": 35821019786
          },
          "key": "\"-\"",
          "doc_count": 43579839
        }
      ]
    }
  }
}

Is there anything I can do to alias these values so that they're accessible from my report? I must have to pass in the key somehow. I attempted to use the 'Terms Aggregation Bucket Script', but I'm not yet getting that process without an error either.


(system) #3