1// Copyright 2012-2015 Oliver Eilhard. All rights reserved.
2// Use of this source code is governed by a MIT-license.
3// See http://olivere.mit-license.org/license.txt for details.
4
5package elastic
6
7// NestedAggregation is a special single bucket aggregation that enables
8// aggregating nested documents.
9// See: http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-aggregations-bucket-nested-aggregation.html
10type NestedAggregation struct {
11	path            string
12	subAggregations map[string]Aggregation
13}
14
15func NewNestedAggregation() NestedAggregation {
16	a := NestedAggregation{
17		subAggregations: make(map[string]Aggregation),
18	}
19	return a
20}
21
22func (a NestedAggregation) SubAggregation(name string, subAggregation Aggregation) NestedAggregation {
23	a.subAggregations[name] = subAggregation
24	return a
25}
26
27func (a NestedAggregation) Path(path string) NestedAggregation {
28	a.path = path
29	return a
30}
31
32func (a NestedAggregation) Source() interface{} {
33	// Example:
34	//	{
35	//     "query" : {
36	//         "match" : { "name" : "led tv" }
37	//     }
38	//     "aggs" : {
39	//         "resellers" : {
40	//             "nested" : {
41	//                 "path" : "resellers"
42	//             },
43	//             "aggs" : {
44	//                 "min_price" : { "min" : { "field" : "resellers.price" } }
45	//             }
46	//         }
47	//     }
48	//	}
49	// This method returns only the { "nested" : {} } part.
50
51	source := make(map[string]interface{})
52	opts := make(map[string]interface{})
53	source["nested"] = opts
54
55	opts["path"] = a.path
56
57	// AggregationBuilder (SubAggregations)
58	if len(a.subAggregations) > 0 {
59		aggsMap := make(map[string]interface{})
60		source["aggregations"] = aggsMap
61		for name, aggregate := range a.subAggregations {
62			aggsMap[name] = aggregate.Source()
63		}
64	}
65
66	return source
67}
68