Average value of buckets in wide range

If the criteria is to always take the status with the greatest count, a terms agg on the state field, ordered by doc_count descending and size 1 will work. Basically, it aggregates together all the states at time=t, partitioned by each user, and then only retains the state with the greatest doc count... give you the "averaged" state for that user at that point in time.

This doesn't handle more complex situations like what happens if there is a tie. For that you'd probably have to set the size to >1 and do some client-side processing to figure out which value to use.

Here's an example:

PUT /test/
{
  "mappings": {
    "_doc": {
      "properties": {
        "state": {
          "type": "keyword"
        }
      }
    }
  }
}

POST /test/_doc/_bulk
{ "index" : {} }
{ "user": 1, "timestamp": 1, "state": "started"  }
{ "index" : {} }
{ "user": 1, "timestamp": 1, "state": "started"  }
{ "index" : {} }
{ "user": 1, "timestamp": 1, "state": "stopped"  }
{ "index" : {} }
{ "user": 2, "timestamp": 1, "state": "started"  }
{ "index" : {} }
{ "user": 2, "timestamp": 1, "state": "stopped"  }
{ "index" : {} }
{ "user": 2, "timestamp": 1, "state": "stopped"  }

GET /test/_search
{
  "size": 0,
  "aggs": {
    "user": {
      "terms": {
        "field": "user"
      },
      "aggs": {
        "histo": {
          "date_histogram": {
            "field": "timestamp",
            "interval": 1
          },
          "aggs": {
            "states": {
              "terms": {
                "field": "state",
                "order": {
                  "_count": "desc"
                },
                "size": 1
              }
            }
          }
        }
      }
    }
  }
}