/
query_builder_numerical.go
91 lines (78 loc) · 2.84 KB
/
query_builder_numerical.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* _ _
*__ _____ __ ___ ___ __ _| |_ ___
*\ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
* \ V V / __/ (_| |\ V /| | (_| | || __/
* \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
*
* Copyright © 2016 - 2019 Weaviate. All rights reserved.
* LICENSE: https://github.com/creativesoftwarefdn/weaviate/blob/develop/LICENSE.md
* DESIGN & CONCEPT: Bob van Luijt (@bobvanluijt)
* CONTACT: hello@creativesoftwarefdn.org
*/
package aggregate
import (
"fmt"
"strings"
"github.com/creativesoftwarefdn/weaviate/graphqlapi/local/aggregate"
"github.com/creativesoftwarefdn/weaviate/gremlin"
)
type aggregation struct {
label string
aggregation *gremlin.Query
}
func (b *Query) numericalProp(prop aggregate.Property) (*propertyAggregation, error) {
aggregators := []*aggregation{}
for _, aggregator := range prop.Aggregators {
newAggregator, err := b.numericalPropAggregators(aggregator)
if err != nil {
return nil, fmt.Errorf("cannot build query for aggregator prop '%s': %s", aggregator, err)
}
if newAggregator == nil {
continue
}
aggregators = append(aggregators, newAggregator)
}
return b.mergeAggregators(aggregators, prop)
}
func (b *Query) numericalPropAggregators(aggregator aggregate.Aggregator) (*aggregation, error) {
switch aggregator {
case aggregate.Count:
return &aggregation{label: string(aggregator), aggregation: gremlin.New().Count()}, nil
case aggregate.Mean:
return &aggregation{label: string(aggregator), aggregation: gremlin.New().Mean()}, nil
case aggregate.Mode:
return &aggregation{
label: string(aggregator),
aggregation: gremlin.New().GroupCount().OrderLocalByValuesSelectKeysLimit("decr", 1),
}, nil
case aggregate.Sum:
return &aggregation{label: string(aggregator), aggregation: gremlin.New().Sum()}, nil
case aggregate.Maximum:
return &aggregation{label: string(aggregator), aggregation: gremlin.New().Max()}, nil
case aggregate.Minimum:
return &aggregation{label: string(aggregator), aggregation: gremlin.New().Min()}, nil
default:
return nil, fmt.Errorf("analysis '%s' not supported for int prop", aggregator)
}
}
func (b *Query) mergeAggregators(aggregationQueries []*aggregation,
prop aggregate.Property) (*propertyAggregation, error) {
selections := []string{}
matchFragments := []string{}
for _, a := range aggregationQueries {
mappedPropName := b.mappedPropertyName(b.params.ClassName, prop.Name)
selection := fmt.Sprintf("%s__%s", mappedPropName, a.label)
q := gremlin.New().
As("a").
Unfold().
Values([]string{mappedPropName}).
Raw("." + a.aggregation.String()).
As(selection)
matchFragments = append(matchFragments, q.String())
selections = append(selections, selection)
}
return &propertyAggregation{
matchQueryFragment: gremlin.New().Raw(strings.Join(matchFragments, ",")),
selections: selections,
}, nil
}