Elasticsearch 1.0 aggregations replaced facets

Facets answered exactly one question — how many documents per term, per range, per date interval — and could not be nested, so a sidebar showing brands within a category needed a separate request per category and a merge in application code. Aggregations arrived with 1.0 in February, take the same shapes as inputs, and compose.

{
  "query": { "term": { "category_id": 17 } },
  "size": 0,
  "aggs": {
    "brands": {
      "terms": { "field": "brand", "size": 20 },
      "aggs": {
        "avg_price": { "avg": { "field": "price" } },
        "price_bands": {
          "range": {
            "field": "price",
            "ranges": [
              { "to": 5000 },
              { "from": 5000, "to": 20000 },
              { "from": 20000 }
            ]
          }
        }
      }
    }
  }
}

The nesting is the difference. A terms aggregation produces buckets, every bucket may carry its own sub-aggregations, and so the average price per brand and the price distribution within each brand come back from the request that was being made anyway. "size": 0 drops the hits entirely when only counts are wanted. Facets still work in 1.x and are deprecated, so the migration is not urgent — but it is not mechanical either. A terms aggregation over a multi-shard index is approximate, because each shard returns its own top N before they are merged, so counts near the bottom of a long tail can be wrong. shard_size trades memory for accuracy there. Facets had exactly the same problem and never mentioned it.