-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathcustom_script_query_parse.go
More file actions
107 lines (93 loc) · 2.73 KB
/
custom_script_query_parse.go
File metadata and controls
107 lines (93 loc) · 2.73 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package cbft
import (
"encoding/json"
"fmt"
"strings"
"github.com/blevesearch/bleve/v2/search/query"
jsoniter "github.com/json-iterator/go"
)
type customQueryParams struct {
Fields []string `json:"fields,omitempty"`
Params map[string]interface{} `json:"params,omitempty"`
Source string `json:"source,omitempty"`
}
type customQueryInput struct {
Query json.RawMessage `json:"query"`
customQueryParams
}
func parseCustomFilterQuery(input []byte) (query.Query, error) {
rv, child, err := parseCustomQueryInput(input, "custom_filter")
if err != nil {
return nil, err
}
filterFn, err := buildFilterFunc(rv.Source, rv.Params, rv.Fields)
if err != nil {
return nil, err
}
return query.NewCustomFilterQueryWithFilter(child, filterFn, rv.Fields,
makeCustomQueryPayload(rv.customQueryParams)), nil
}
func parseCustomScoreQuery(input []byte) (query.Query, error) {
rv, child, err := parseCustomQueryInput(input, "custom_score")
if err != nil {
return nil, err
}
scoreFn, err := buildScoreFunc(rv.Source, rv.Params, rv.Fields)
if err != nil {
return nil, err
}
return query.NewCustomScoreQueryWithScorer(child, scoreFn, rv.Fields,
makeCustomQueryPayload(rv.customQueryParams)), nil
}
func parseCustomQueryInput(input []byte, key string) (*customQueryInput, query.Query, error) {
var rv struct {
Custom customQueryInput `json:"-"`
}
switch key {
case "custom_filter":
var payload struct {
Custom customQueryInput `json:"custom_filter"`
}
if err := jsoniter.Unmarshal(input, &payload); err != nil {
return nil, nil, err
}
rv.Custom = payload.Custom
case "custom_score":
var payload struct {
Custom customQueryInput `json:"custom_score"`
}
if err := jsoniter.Unmarshal(input, &payload); err != nil {
return nil, nil, err
}
rv.Custom = payload.Custom
default:
return nil, nil, fmt.Errorf("unsupported custom query type %q", key)
}
if rv.Custom.Query == nil {
return nil, nil, fmt.Errorf("%s query must have a query", strings.ReplaceAll(key, "_", " "))
}
if rv.Custom.Source == "" {
return nil, nil, fmt.Errorf("%s query must have source", strings.ReplaceAll(key, "_", " "))
}
// Keep the child as RawMessage so nested queries recurse through cbft's
// local parseQuery() path instead of bypassing it with bleve's generic
// JSON unmarshal path.
child, err := parseQuery(rv.Custom.Query)
if err != nil {
return nil, nil, err
}
return &rv.Custom, child, nil
}
func makeCustomQueryPayload(params customQueryParams) map[string]interface{} {
payload := make(map[string]interface{}, 2)
if len(params.Params) > 0 {
payload["params"] = params.Params
}
if params.Source != "" {
payload["source"] = params.Source
}
if len(payload) == 0 {
return nil
}
return payload
}