148 lines
2.9 KiB
Go
148 lines
2.9 KiB
Go
package elasticsearch
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// Helper function which turns a map of strings into url.Values, omitting empty
|
|
// values.
|
|
func values(v map[string]string) url.Values {
|
|
values := url.Values{}
|
|
|
|
for key, value := range v {
|
|
if value != "" {
|
|
values.Set(key, value)
|
|
}
|
|
}
|
|
|
|
return values
|
|
}
|
|
|
|
// Fireable defines anything which can be fired against the search cluster.
|
|
type Fireable interface {
|
|
Request(uri *url.URL) (*http.Request, error)
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
type SearchParams struct {
|
|
Indices []string `json:"index,omitempty"`
|
|
Types []string `json:"type,omitempty"`
|
|
|
|
Routing string `json:"routing,omitempty"`
|
|
Preference string `json:"preference,omitempty"`
|
|
SearchType string `json:"search_type,omitempty"`
|
|
}
|
|
|
|
func (p SearchParams) Values() url.Values {
|
|
return values(map[string]string{
|
|
"routing": p.Routing,
|
|
"preference": p.Preference,
|
|
"search_type": p.SearchType,
|
|
})
|
|
}
|
|
|
|
type SearchRequest struct {
|
|
Params SearchParams
|
|
Query SubQuery
|
|
}
|
|
|
|
func (r SearchRequest) EncodeMultiHeader(enc *json.Encoder) error {
|
|
return enc.Encode(r.Params)
|
|
}
|
|
|
|
func (r SearchRequest) EncodeQuery(enc *json.Encoder) error {
|
|
return enc.Encode(r.Query)
|
|
}
|
|
|
|
func (r SearchRequest) Request(uri *url.URL) (*http.Request, error) {
|
|
uri.Path = r.Path()
|
|
uri.RawQuery = r.Params.Values().Encode()
|
|
|
|
buf := new(bytes.Buffer)
|
|
enc := json.NewEncoder(buf)
|
|
|
|
if err := r.EncodeQuery(enc); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return http.NewRequest("GET", uri.String(), buf)
|
|
}
|
|
|
|
func (r SearchRequest) Path() string {
|
|
switch true {
|
|
case len(r.Params.Indices) == 0 && len(r.Params.Types) == 0:
|
|
return fmt.Sprintf(
|
|
"/_search", // all indices, all types
|
|
)
|
|
|
|
case len(r.Params.Indices) > 0 && len(r.Params.Types) == 0:
|
|
return fmt.Sprintf(
|
|
"/%s/_search",
|
|
strings.Join(r.Params.Indices, ","),
|
|
)
|
|
|
|
case len(r.Params.Indices) == 0 && len(r.Params.Types) > 0:
|
|
return fmt.Sprintf(
|
|
"/_all/%s/_search",
|
|
strings.Join(r.Params.Types, ","),
|
|
)
|
|
|
|
case len(r.Params.Indices) > 0 && len(r.Params.Types) > 0:
|
|
return fmt.Sprintf(
|
|
"/%s/%s/_search",
|
|
strings.Join(r.Params.Indices, ","),
|
|
strings.Join(r.Params.Types, ","),
|
|
)
|
|
}
|
|
panic("unreachable")
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
type MultiSearchParams struct {
|
|
Indices []string
|
|
Types []string
|
|
|
|
SearchType string
|
|
}
|
|
|
|
func (p MultiSearchParams) Values() url.Values {
|
|
return values(map[string]string{
|
|
"search_type": p.SearchType,
|
|
})
|
|
}
|
|
|
|
type MultiSearchRequest struct {
|
|
Params MultiSearchParams
|
|
Requests []SearchRequest
|
|
}
|
|
|
|
func (r MultiSearchRequest) Request(uri *url.URL) (*http.Request, error) {
|
|
uri.Path = "/_msearch"
|
|
uri.RawQuery = r.Params.Values().Encode()
|
|
|
|
buf := new(bytes.Buffer)
|
|
enc := json.NewEncoder(buf)
|
|
|
|
for _, req := range r.Requests {
|
|
if err := req.EncodeMultiHeader(enc); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := req.EncodeQuery(enc); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return http.NewRequest("GET", uri.String(), buf)
|
|
}
|