func ExampleAggregations() { // Get a client to the local Elasticsearch instance. client, err := elastic.NewClient() if err != nil { // Handle error panic(err) } // Create an aggregation for users and a sub-aggregation for a date histogram of tweets (per year). timeline := elastic.NewTermsAggregation().Field("user").Size(10).OrderByCountDesc() histogram := elastic.NewDateHistogramAggregation().Field("created").Interval("year") timeline = timeline.SubAggregation("history", histogram) // Search with a term query searchResult, err := client.Search(). Index("twitter"). // search in index "twitter" Query(elastic.NewMatchAllQuery()). // return all results, but ... SearchType("count"). // ... do not return hits, just the count Aggregation("timeline", timeline). // add our aggregation to the query Pretty(true). // pretty print request and response JSON Do() // execute if err != nil { // Handle error panic(err) } // Access "timeline" aggregate in search result. agg, found := searchResult.Aggregations.Terms("timeline") if !found { log.Fatalf("we sould have a terms aggregation called %q", "timeline") } for _, userBucket := range agg.Buckets { // Every bucket should have the user field as key. user := userBucket.Key // The sub-aggregation history should have the number of tweets per year. histogram, found := userBucket.DateHistogram("history") if found { for _, year := range histogram.Buckets { fmt.Printf("user %q has %d tweets in %q\n", user, year.DocCount, year.KeyAsString) } } } }
// LSDateHistorgram builds the aggregation query using subaggregations. The result is a grouped timer series // that Bosun can understand func LSDateHistogram(e *State, T miniprofiler.Timer, index_root, keystring, filter, interval, sduration, eduration, stat_field, rstat string, size int) (r *Results, err error) { r = new(Results) req, err := LSBaseQuery(e.now, index_root, e.logstashHosts, keystring, filter, sduration, eduration, size) if err != nil { return nil, err } ts := elastic.NewDateHistogramAggregation().Field("@timestamp").Interval(strings.Replace(interval, "M", "n", -1)).MinDocCount(0) ds, err := opentsdb.ParseDuration(interval) if err != nil { return nil, err } if stat_field != "" { ts = ts.SubAggregation("stats", elastic.NewExtendedStatsAggregation().Field(stat_field)) switch rstat { case "avg", "min", "max", "sum", "sum_of_squares", "variance", "std_deviation": default: return r, fmt.Errorf("stat function %v not a valid option", rstat) } } if keystring == "" { req.Source = req.Source.Aggregation("ts", ts) result, err := timeLSRequest(e, T, req) if err != nil { return nil, err } ts, found := result.Aggregations.DateHistogram("ts") if !found { return nil, fmt.Errorf("expected time series not found in elastic reply") } series := make(Series) for _, v := range ts.Buckets { val := processBucketItem(v, rstat, ds) if val != nil { series[time.Unix(v.Key/1000, 0).UTC()] = *val } } if len(series) == 0 { return r, nil } r.Results = append(r.Results, &Result{ Value: series, Group: make(opentsdb.TagSet), }) return r, nil } keys := req.KeyMatches aggregation := elastic.NewTermsAggregation().Field(keys[len(keys)-1].Key).Size(0) aggregation = aggregation.SubAggregation("ts", ts) for i := len(keys) - 2; i > -1; i-- { aggregation = elastic.NewTermsAggregation().Field(keys[i].Key).Size(0).SubAggregation("g_"+keys[i+1].Key, aggregation) } req.Source = req.Source.Aggregation("g_"+keys[0].Key, aggregation) result, err := timeLSRequest(e, T, req) if err != nil { return nil, err } top, ok := result.Aggregations.Terms("g_" + keys[0].Key) if !ok { return nil, fmt.Errorf("top key g_%v not found in result", keys[0].Key) } var desc func(*elastic.AggregationBucketKeyItem, opentsdb.TagSet, []lsKeyMatch) error desc = func(b *elastic.AggregationBucketKeyItem, tags opentsdb.TagSet, keys []lsKeyMatch) error { if ts, found := b.DateHistogram("ts"); found { if e.squelched(tags) { return nil } series := make(Series) for _, v := range ts.Buckets { val := processBucketItem(v, rstat, ds) if val != nil { series[time.Unix(v.Key/1000, 0).UTC()] = *val } } if len(series) == 0 { return nil } r.Results = append(r.Results, &Result{ Value: series, Group: tags.Copy(), }) return nil } if len(keys) < 1 { return nil } n, _ := b.Aggregations.Terms("g_" + keys[0].Key) for _, item := range n.Buckets { key := fmt.Sprint(item.Key) if keys[0].Pattern != nil && !keys[0].Pattern.MatchString(key) { continue } tags[keys[0].Key] = key if err := desc(item, tags.Copy(), keys[1:]); err != nil { return err } } return nil } for _, b := range top.Buckets { tags := make(opentsdb.TagSet) key := fmt.Sprint(b.Key) if keys[0].Pattern != nil && !keys[0].Pattern.MatchString(key) { continue } tags[keys[0].Key] = key if err := desc(b, tags, keys[1:]); err != nil { return nil, err } } return r, nil }