summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/olivere
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gopkg.in/olivere')
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/.travis.yml2
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS6
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/bulk.go2
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/bulk_test.go27
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/client.go13
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml2
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go12
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/msearch.go2
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/request_test.go14
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/response.go4
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/response_test.go48
-rwxr-xr-xvendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh2
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/search.go31
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/search_request.go9
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go106
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/setup_test.go8
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/suggester_context.go113
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go55
18 files changed, 418 insertions, 38 deletions
diff --git a/vendor/gopkg.in/olivere/elastic.v5/.travis.yml b/vendor/gopkg.in/olivere/elastic.v5/.travis.yml
index 703fa01be..6f718f66a 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/.travis.yml
+++ b/vendor/gopkg.in/olivere/elastic.v5/.travis.yml
@@ -12,5 +12,5 @@ services:
- docker
before_install:
- sudo sysctl -w vm.max_map_count=262144
- - docker run --rm --privileged=true -p 9200:9200 -p 9300:9300 -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" docker.elastic.co/elasticsearch/elasticsearch:5.6.1 elasticsearch -Expack.security.enabled=false -Escript.inline=true -Escript.stored=true -Escript.file=true -Enetwork.host=_local_,_site_ -Enetwork.publish_host=_local_ >& /dev/null &
+ - docker run --rm --privileged=true -p 9200:9200 -p 9300:9300 -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" docker.elastic.co/elasticsearch/elasticsearch:5.6.3 elasticsearch -Expack.security.enabled=false -Escript.inline=true -Escript.stored=true -Escript.file=true -Enetwork.host=_local_,_site_ -Enetwork.publish_host=_local_ >& /dev/null &
- sleep 30
diff --git a/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS b/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS
index 572caf62d..e3ded87cd 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS
+++ b/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS
@@ -20,6 +20,7 @@ Andrew Dunham [@andrew-d](https://github.com/andrew-d)
Andrew Gaul [@andrewgaul](https://github.com/andrewgaul)
Andy Walker [@alaska](https://github.com/alaska)
Arquivei [@arquivei](https://github.com/arquivei)
+arthurgustin [@arthurgustin](https://github.com/arthurgustin)
Benjamin Fernandes [@LotharSee](https://github.com/LotharSee)
Benjamin Zarzycki [@kf6nux](https://github.com/kf6nux)
Braden Bassingthwaite [@bbassingthwaite-va](https://github.com/bbassingthwaite-va)
@@ -65,13 +66,16 @@ Joe Buck [@four2five](https://github.com/four2five)
John Barker [@j16r](https://github.com/j16r)
John Goodall [@jgoodall](https://github.com/jgoodall)
John Stanford [@jxstanford](https://github.com/jxstanford)
+Josh Chorlton [@jchorl](https://github.com/jchorl)
jun [@coseyo](https://github.com/coseyo)
Junpei Tsuji [@jun06t](https://github.com/jun06t)
Keith Hatton [@khatton-ft](https://github.com/khatton-ft)
+kel [@liketic](https://github.com/liketic)
Kenta SUZUKI [@suzuken](https://github.com/suzuken)
Kevin Mulvey [@kmulvey](https://github.com/kmulvey)
Kyle Brandt [@kylebrandt](https://github.com/kylebrandt)
Leandro Piccilli [@lpic10](https://github.com/lpic10)
+M. Zulfa Achsani [@misterciput](https://github.com/misterciput)
Maciej Lisiewski [@c2h5oh](https://github.com/c2h5oh)
Mara Kim [@autochthe](https://github.com/autochthe)
Marcy Buccellato [@marcybuccellato](https://github.com/marcybuccellato)
@@ -88,6 +92,7 @@ Nick K [@utrack](https://github.com/utrack)
Nick Whyte [@nickw444](https://github.com/nickw444)
Nicolae Vartolomei [@nvartolomei](https://github.com/nvartolomei)
Orne Brocaar [@brocaar](https://github.com/brocaar)
+Paul [@eyeamera](https://github.com/eyeamera)
Pete C [@peteclark-ft](https://github.com/peteclark-ft)
Radoslaw Wesolowski [r--w](https://github.com/r--w)
Ryan Schmukler [@rschmukler](https://github.com/rschmukler)
@@ -110,4 +115,5 @@ Wyndham Blanton [@wyndhblb](https://github.com/wyndhblb)
Yarden Bar [@ayashjorden](https://github.com/ayashjorden)
zakthomas [@zakthomas](https://github.com/zakthomas)
singham [@zhaochenxiao90](https://github.com/zhaochenxiao90)
+@林 [@zplzpl](https://github.com/zplzpl)
Roman Colohanin [@zuzmic](https://github.com/zuzmic)
diff --git a/vendor/gopkg.in/olivere/elastic.v5/bulk.go b/vendor/gopkg.in/olivere/elastic.v5/bulk.go
index eac240ddb..f2fa0ea73 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/bulk.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/bulk.go
@@ -234,7 +234,7 @@ func (s *BulkService) Do(ctx context.Context) (*BulkResponse, error) {
}
// Get response
- res, err := s.client.PerformRequest(ctx, "POST", path, params, body)
+ res, err := s.client.PerformRequestWithContentType(ctx, "POST", path, params, body, "application/x-ndjson")
if err != nil {
return nil, err
}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go b/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go
index fba52be73..394439630 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go
@@ -7,6 +7,9 @@ package elastic
import (
"context"
"encoding/json"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
"testing"
)
@@ -505,3 +508,27 @@ func BenchmarkBulkEstimatedSizeInBytesWith100Requests(b *testing.B) {
b.ReportAllocs()
benchmarkBulkEstimatedSizeInBytes = result // ensure the compiler doesn't optimize
}
+
+func TestBulkContentType(t *testing.T) {
+ var header http.Header
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ header = r.Header
+ fmt.Fprintln(w, `{}`)
+ }))
+ defer ts.Close()
+
+ client, err := NewSimpleClient(SetURL(ts.URL))
+ if err != nil {
+ t.Fatal(err)
+ }
+ indexReq := NewBulkIndexRequest().Index(testIndexName).Type("tweet").Id("1").Doc(tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."})
+ if _, err := client.Bulk().Add(indexReq).Do(context.Background()); err != nil {
+ t.Fatal(err)
+ }
+ if header == nil {
+ t.Fatalf("expected header, got %v", header)
+ }
+ if want, have := "application/x-ndjson", header.Get("Content-Type"); want != have {
+ t.Fatalf("Content-Type: want %q, have %q", want, have)
+ }
+}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/client.go b/vendor/gopkg.in/olivere/elastic.v5/client.go
index 13b45d831..9a48d9ac7 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/client.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/client.go
@@ -26,7 +26,7 @@ import (
const (
// Version is the current version of Elastic.
- Version = "5.0.48"
+ Version = "5.0.53"
// DefaultURL is the default endpoint of Elasticsearch on the local machine.
// It is used e.g. when initializing a new Client without a specific URL.
@@ -1168,12 +1168,18 @@ func (c *Client) mustActiveConn() error {
}
// PerformRequest does a HTTP request to Elasticsearch.
+// See PerformRequestWithContentType for details.
+func (c *Client) PerformRequest(ctx context.Context, method, path string, params url.Values, body interface{}, ignoreErrors ...int) (*Response, error) {
+ return c.PerformRequestWithContentType(ctx, method, path, params, body, "application/json", ignoreErrors...)
+}
+
+// PerformRequestWithContentType executes a HTTP request with a specific content type.
// It returns a response (which might be nil) and an error on failure.
//
// Optionally, a list of HTTP error codes to ignore can be passed.
// This is necessary for services that expect e.g. HTTP status 404 as a
// valid outcome (Exists, IndicesExists, IndicesTypeExists).
-func (c *Client) PerformRequest(ctx context.Context, method, path string, params url.Values, body interface{}, ignoreErrors ...int) (*Response, error) {
+func (c *Client) PerformRequestWithContentType(ctx context.Context, method, path string, params url.Values, body interface{}, contentType string, ignoreErrors ...int) (*Response, error) {
start := time.Now().UTC()
c.mu.RLock()
@@ -1236,6 +1242,9 @@ func (c *Client) PerformRequest(ctx context.Context, method, path string, params
if basicAuth {
req.SetBasicAuth(basicAuthUsername, basicAuthPassword)
}
+ if contentType != "" {
+ req.Header.Set("Content-Type", contentType)
+ }
// Set body
if body != nil {
diff --git a/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml b/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml
index 046096db2..002eac7fa 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml
+++ b/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml
@@ -2,7 +2,7 @@ version: '3'
services:
elasticsearch:
- image: docker.elastic.co/elasticsearch/elasticsearch:5.6.0
+ image: docker.elastic.co/elasticsearch/elasticsearch:5.6.3
# container_name: elasticsearch
hostname: elasticsearch
environment:
diff --git a/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go b/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go
index 79324d75f..dbc83ac2c 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go
@@ -14,11 +14,10 @@ import (
)
// RefreshService explicitly refreshes one or more indices.
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/indices-refresh.html.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/indices-refresh.html.
type RefreshService struct {
client *Client
index []string
- force *bool
pretty bool
}
@@ -36,12 +35,6 @@ func (s *RefreshService) Index(index ...string) *RefreshService {
return s
}
-// Force forces a refresh.
-func (s *RefreshService) Force(force bool) *RefreshService {
- s.force = &force
- return s
-}
-
// Pretty asks Elasticsearch to return indented JSON.
func (s *RefreshService) Pretty(pretty bool) *RefreshService {
s.pretty = pretty
@@ -66,9 +59,6 @@ func (s *RefreshService) buildURL() (string, url.Values, error) {
// Add query string parameters
params := url.Values{}
- if s.force != nil {
- params.Set("force", fmt.Sprintf("%v", *s.force))
- }
if s.pretty {
params.Set("pretty", fmt.Sprintf("%v", s.pretty))
}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/msearch.go b/vendor/gopkg.in/olivere/elastic.v5/msearch.go
index 52ca9ee74..5d0949d9c 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/msearch.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/msearch.go
@@ -68,7 +68,7 @@ func (s *MultiSearchService) Do(ctx context.Context) (*MultiSearchResult, error)
if err != nil {
return nil, err
}
- body, err := json.Marshal(sr.body())
+ body, err := json.Marshal(sr.Body())
if err != nil {
return nil, err
}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/request_test.go b/vendor/gopkg.in/olivere/elastic.v5/request_test.go
index 2a2d229df..d5ae4f800 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/request_test.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/request_test.go
@@ -8,6 +8,20 @@ import "testing"
var testReq *Request // used as a temporary variable to avoid compiler optimizations in tests/benchmarks
+func TestRequestSetContentType(t *testing.T) {
+ req, err := NewRequest("GET", "/")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if want, have := "application/json", req.Header.Get("Content-Type"); want != have {
+ t.Fatalf("want %q, have %q", want, have)
+ }
+ req.Header.Set("Content-Type", "application/x-ndjson")
+ if want, have := "application/x-ndjson", req.Header.Get("Content-Type"); want != have {
+ t.Fatalf("want %q, have %q", want, have)
+ }
+}
+
func BenchmarkRequestSetBodyString(b *testing.B) {
req, err := NewRequest("GET", "/")
if err != nil {
diff --git a/vendor/gopkg.in/olivere/elastic.v5/response.go b/vendor/gopkg.in/olivere/elastic.v5/response.go
index e7380d98a..4fcdc32d6 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/response.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/response.go
@@ -34,9 +34,7 @@ func (c *Client) newResponse(res *http.Response) (*Response, error) {
}
// HEAD requests return a body but no content
if len(slurp) > 0 {
- if err := c.decoder.Decode(slurp, &r.Body); err != nil {
- return nil, err
- }
+ r.Body = json.RawMessage(slurp)
}
}
return r, nil
diff --git a/vendor/gopkg.in/olivere/elastic.v5/response_test.go b/vendor/gopkg.in/olivere/elastic.v5/response_test.go
new file mode 100644
index 000000000..e62773403
--- /dev/null
+++ b/vendor/gopkg.in/olivere/elastic.v5/response_test.go
@@ -0,0 +1,48 @@
+// Copyright 2012-present Oliver Eilhard. All rights reserved.
+// Use of this source code is governed by a MIT-license.
+// See http://olivere.mit-license.org/license.txt for details.
+
+package elastic
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "testing"
+)
+
+func BenchmarkResponse(b *testing.B) {
+ c := &Client{
+ decoder: &DefaultDecoder{},
+ }
+
+ var resp *Response
+ for n := 0; n < b.N; n++ {
+ iteration := fmt.Sprint(n)
+ body := fmt.Sprintf(`{"n":%d}`, n)
+ res := &http.Response{
+ Header: http.Header{
+ "X-Iteration": []string{iteration},
+ },
+ Body: ioutil.NopCloser(bytes.NewBufferString(body)),
+ StatusCode: http.StatusOK,
+ }
+ var err error
+ resp, err = c.newResponse(res)
+ if err != nil {
+ b.Fatal(err)
+ }
+ /*
+ if want, have := body, string(resp.Body); want != have {
+ b.Fatalf("want %q, have %q", want, have)
+ }
+ //*/
+ /*
+ if want, have := iteration, resp.Header.Get("X-Iteration"); want != have {
+ b.Fatalf("want %q, have %q", want, have)
+ }
+ //*/
+ }
+ _ = resp
+}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh b/vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh
new file mode 100755
index 000000000..6a9864668
--- /dev/null
+++ b/vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh
@@ -0,0 +1,2 @@
+VERSION=5.6.3
+docker run --rm --privileged=true -p 9200:9200 -p 9300:9300 -v "$PWD/etc:/usr/share/elasticsearch/config" -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" docker.elastic.co/elasticsearch/elasticsearch:$VERSION elasticsearch -Expack.security.enabled=false -Escript.inline=true -Escript.stored=true -Escript.file=true
diff --git a/vendor/gopkg.in/olivere/elastic.v5/search.go b/vendor/gopkg.in/olivere/elastic.v5/search.go
index 301550815..7121d5545 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/search.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/search.go
@@ -60,7 +60,7 @@ func (s *SearchService) Source(source interface{}) *SearchService {
// FilterPath allows reducing the response, a mechanism known as
// response filtering and described here:
-// https://www.elastic.co/guide/en/elasticsearch/reference/5.2/common-options.html#common-options-response-filtering.
+// https://www.elastic.co/guide/en/elasticsearch/reference/5.6/common-options.html#common-options-response-filtering.
func (s *SearchService) FilterPath(filterPath ...string) *SearchService {
s.filterPath = append(s.filterPath, filterPath...)
return s
@@ -113,7 +113,7 @@ func (s *SearchService) TimeoutInMillis(timeoutInMillis int) *SearchService {
// SearchType sets the search operation type. Valid values are:
// "query_then_fetch", "query_and_fetch", "dfs_query_then_fetch",
// "dfs_query_and_fetch", "count", "scan".
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-search-type.html
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-search-type.html
// for details.
func (s *SearchService) SearchType(searchType string) *SearchService {
s.searchType = searchType
@@ -271,7 +271,7 @@ func (s *SearchService) StoredFields(fields ...string) *SearchService {
// SearchAfter allows a different form of pagination by using a live cursor,
// using the results of the previous page to help the retrieval of the next.
//
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-search-after.html
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-search-after.html
func (s *SearchService) SearchAfter(sortValues ...interface{}) *SearchService {
s.searchSource = s.searchSource.SearchAfter(sortValues...)
return s
@@ -473,7 +473,7 @@ type SearchHitInnerHits struct {
}
// SearchExplanation explains how the score for a hit was computed.
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-explain.html.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-explain.html.
type SearchExplanation struct {
Value float64 `json:"value"` // e.g. 1.0
Description string `json:"description"` // e.g. "boost" or "ConstantScore(*:*), product of:"
@@ -483,11 +483,11 @@ type SearchExplanation struct {
// Suggest
// SearchSuggest is a map of suggestions.
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters.html.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters.html.
type SearchSuggest map[string][]SearchSuggestion
// SearchSuggestion is a single search suggestion.
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters.html.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters.html.
type SearchSuggestion struct {
Text string `json:"text"`
Offset int `json:"offset"`
@@ -496,14 +496,17 @@ type SearchSuggestion struct {
}
// SearchSuggestionOption is an option of a SearchSuggestion.
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters.html.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters.html.
type SearchSuggestionOption struct {
- Text string `json:"text"`
- Index string `json:"_index"`
- Type string `json:"_type"`
- Id string `json:"_id"`
- Score float64 `json:"_score"`
- Source *json.RawMessage `json:"_source"`
+ Text string `json:"text"`
+ Index string `json:"_index"`
+ Type string `json:"_type"`
+ Id string `json:"_id"`
+ Score float64 `json:"score"`
+ Highlighted string `json:"highlighted"`
+ CollateMatch bool `json:"collate_match"`
+ Freq int `json:"freq"` // from TermSuggestion.Option in Java API
+ Source *json.RawMessage `json:"_source"`
}
// SearchProfile is a list of shard profiling data collected during
@@ -556,6 +559,6 @@ type ProfileResult struct {
// Highlighting
// SearchHitHighlight is the highlight information of a search hit.
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-highlighting.html
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-highlighting.html
// for a general discussion of highlighting.
type SearchHitHighlight map[string][]string
diff --git a/vendor/gopkg.in/olivere/elastic.v5/search_request.go b/vendor/gopkg.in/olivere/elastic.v5/search_request.go
index ad22a5a3f..03513085f 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/search_request.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/search_request.go
@@ -194,9 +194,12 @@ func (r *SearchRequest) header() interface{} {
return h
}
-// body is used by MultiSearch to get information about the search body
+// Body allows to access the search body of the request, as generated by the DSL.
+// Notice that Body is read-only. You must not change the request body.
+//
+// Body is used e.g. by MultiSearch to get information about the search body
// of one SearchRequest.
-// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-multi-search.html
-func (r *SearchRequest) body() interface{} {
+// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-multi-search.html
+func (r *SearchRequest) Body() interface{} {
return r.source
}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go b/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go
index 78232e9d6..a555e3462 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go
@@ -238,3 +238,109 @@ func TestCompletionSuggester(t *testing.T) {
t.Errorf("expected Text = 'Golang'; got %s", myOption.Text)
}
}
+
+func TestContextSuggester(t *testing.T) {
+ client := setupTestClientAndCreateIndex(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
+
+ // TODO make a nice way of creating tweets, as currently the context fields are unsupported as part of the suggestion fields
+ tweet1 := `
+ {
+ "user":"olivere",
+ "message":"Welcome to Golang and Elasticsearch.",
+ "retweets":0,
+ "created":"0001-01-01T00:00:00Z",
+ "suggest_field":{
+ "input":[
+ "Golang",
+ "Elasticsearch"
+ ],
+ "contexts":{
+ "user_name": ["olivere"]
+ }
+ }
+ }
+ `
+ tweet2 := `
+ {
+ "user":"sandrae",
+ "message":"I like golfing",
+ "retweets":0,
+ "created":"0001-01-01T00:00:00Z",
+ "suggest_field":{
+ "input":[
+ "Golfing"
+ ],
+ "contexts":{
+ "user_name": ["sandrae"]
+ }
+ }
+ }
+ `
+
+ // Add all documents
+ _, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyString(tweet1).Do(context.TODO())
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ _, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyString(tweet2).Do(context.TODO())
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ _, err = client.Flush().Index(testIndexName).Do(context.TODO())
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ suggesterName := "my-suggestions"
+ cs := NewContextSuggester(suggesterName)
+ cs = cs.Prefix("Gol")
+ cs = cs.Field("suggest_field")
+ cs = cs.ContextQueries(
+ NewSuggesterCategoryQuery("user_name", "olivere"),
+ )
+
+ searchResult, err := client.Search().
+ Index(testIndexName).
+ Suggester(cs).
+ Do(context.TODO())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if searchResult.Suggest == nil {
+ t.Errorf("expected SearchResult.Suggest != nil; got nil")
+ }
+ mySuggestions, found := searchResult.Suggest[suggesterName]
+ if !found {
+ t.Errorf("expected to find SearchResult.Suggest[%s]; got false", suggesterName)
+ }
+ if mySuggestions == nil {
+ t.Errorf("expected SearchResult.Suggest[%s] != nil; got nil", suggesterName)
+ }
+
+ // sandra's tweet is not returned because of the user_name context
+ if len(mySuggestions) != 1 {
+ t.Errorf("expected 1 suggestion; got %d", len(mySuggestions))
+ }
+ mySuggestion := mySuggestions[0]
+ if mySuggestion.Text != "Gol" {
+ t.Errorf("expected Text = 'Gol'; got %s", mySuggestion.Text)
+ }
+ if mySuggestion.Offset != 0 {
+ t.Errorf("expected Offset = %d; got %d", 0, mySuggestion.Offset)
+ }
+ if mySuggestion.Length != 3 {
+ t.Errorf("expected Length = %d; got %d", 3, mySuggestion.Length)
+ }
+ if len(mySuggestion.Options) != 1 {
+ t.Errorf("expected 1 option; got %d", len(mySuggestion.Options))
+ }
+ myOption := mySuggestion.Options[0]
+ if myOption.Text != "Golang" {
+ t.Errorf("expected Text = 'Golang'; got %s", myOption.Text)
+ }
+ if myOption.Id != "1" {
+ t.Errorf("expected Id = '1'; got %s", myOption.Id)
+ }
+}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/setup_test.go b/vendor/gopkg.in/olivere/elastic.v5/setup_test.go
index 7e449c821..df2206a14 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/setup_test.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/setup_test.go
@@ -45,7 +45,13 @@ const (
"type":"geo_point"
},
"suggest_field":{
- "type":"completion"
+ "type":"completion",
+ "contexts":[
+ {
+ "name": "user_name",
+ "type": "category"
+ }
+ ]
}
}
},
diff --git a/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go b/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go
index caf477669..ade099151 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go
@@ -4,8 +4,121 @@
package elastic
+import "errors"
+
// SuggesterContextQuery is used to define context information within
// a suggestion request.
type SuggesterContextQuery interface {
Source() (interface{}, error)
}
+
+// ContextSuggester is a fast suggester for e.g. type-ahead completion that supports filtering and boosting based on contexts.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/current/suggester-context.html
+// for more details.
+type ContextSuggester struct {
+ Suggester
+ name string
+ prefix string
+ field string
+ size *int
+ contextQueries []SuggesterContextQuery
+}
+
+// Creates a new context suggester.
+func NewContextSuggester(name string) *ContextSuggester {
+ return &ContextSuggester{
+ name: name,
+ contextQueries: make([]SuggesterContextQuery, 0),
+ }
+}
+
+func (q *ContextSuggester) Name() string {
+ return q.name
+}
+
+func (q *ContextSuggester) Prefix(prefix string) *ContextSuggester {
+ q.prefix = prefix
+ return q
+}
+
+func (q *ContextSuggester) Field(field string) *ContextSuggester {
+ q.field = field
+ return q
+}
+
+func (q *ContextSuggester) Size(size int) *ContextSuggester {
+ q.size = &size
+ return q
+}
+
+func (q *ContextSuggester) ContextQuery(query SuggesterContextQuery) *ContextSuggester {
+ q.contextQueries = append(q.contextQueries, query)
+ return q
+}
+
+func (q *ContextSuggester) ContextQueries(queries ...SuggesterContextQuery) *ContextSuggester {
+ q.contextQueries = append(q.contextQueries, queries...)
+ return q
+}
+
+// contextSuggesterRequest is necessary because the order in which
+// the JSON elements are routed to Elasticsearch is relevant.
+// We got into trouble when using plain maps because the text element
+// needs to go before the completion element.
+type contextSuggesterRequest struct {
+ Prefix string `json:"prefix"`
+ Completion interface{} `json:"completion"`
+}
+
+// Creates the source for the context suggester.
+func (q *ContextSuggester) Source(includeName bool) (interface{}, error) {
+ cs := &contextSuggesterRequest{}
+
+ if q.prefix != "" {
+ cs.Prefix = q.prefix
+ }
+
+ suggester := make(map[string]interface{})
+ cs.Completion = suggester
+
+ if q.field != "" {
+ suggester["field"] = q.field
+ }
+ if q.size != nil {
+ suggester["size"] = *q.size
+ }
+ switch len(q.contextQueries) {
+ case 0:
+ case 1:
+ src, err := q.contextQueries[0].Source()
+ if err != nil {
+ return nil, err
+ }
+ suggester["context"] = src
+ default:
+ ctxq := make(map[string]interface{})
+ for _, query := range q.contextQueries {
+ src, err := query.Source()
+ if err != nil {
+ return nil, err
+ }
+ // Merge the dictionary into ctxq
+ m, ok := src.(map[string]interface{})
+ if !ok {
+ return nil, errors.New("elastic: context query is not a map")
+ }
+ for k, v := range m {
+ ctxq[k] = v
+ }
+ }
+ suggester["contexts"] = ctxq
+ }
+
+ if !includeName {
+ return cs, nil
+ }
+
+ source := make(map[string]interface{})
+ source[q.name] = cs
+ return source, nil
+}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go b/vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go
new file mode 100644
index 000000000..cd3c5586c
--- /dev/null
+++ b/vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go
@@ -0,0 +1,55 @@
+// Copyright 2012-present Oliver Eilhard. All rights reserved.
+// Use of this source code is governed by a MIT-license.
+// See http://olivere.mit-license.org/license.txt for details.
+
+package elastic
+
+import (
+ "encoding/json"
+ "testing"
+)
+
+func TestContextSuggesterSource(t *testing.T) {
+ s := NewContextSuggester("place_suggestion").
+ Prefix("tim").
+ Field("suggest")
+ src, err := s.Source(true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ data, err := json.Marshal(src)
+ if err != nil {
+ t.Fatalf("marshaling to JSON failed: %v", err)
+ }
+ got := string(data)
+ expected := `{"place_suggestion":{"prefix":"tim","completion":{"field":"suggest"}}}`
+ if got != expected {
+ t.Errorf("expected\n%s\n,got:\n%s", expected, got)
+ }
+}
+
+func TestContextSuggesterSourceWithMultipleContexts(t *testing.T) {
+ s := NewContextSuggester("place_suggestion").
+ Prefix("tim").
+ Field("suggest").
+ ContextQueries(
+ NewSuggesterCategoryQuery("place_type", "cafe", "restaurants"),
+ )
+ src, err := s.Source(true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ data, err := json.Marshal(src)
+ if err != nil {
+ t.Fatalf("marshaling to JSON failed: %v", err)
+ }
+ got := string(data)
+ // Due to the randomization of dictionary key, we could actually have two different valid expected outcomes
+ expected := `{"place_suggestion":{"prefix":"tim","completion":{"context":{"place_type":[{"context":"cafe"},{"context":"restaurants"}]},"field":"suggest"}}}`
+ if got != expected {
+ expected := `{"place_suggestion":{"prefix":"tim","completion":{"context":{"place_type":[{"context":"restaurants"},{"context":"cafe"}]},"field":"suggest"}}}`
+ if got != expected {
+ t.Errorf("expected %s\n,got:\n%s", expected, got)
+ }
+ }
+}