From f698dfea7c6cb058bee5de042f1ad3387f678ab1 Mon Sep 17 00:00:00 2001 From: Oliver Eilhard Date: Mon, 10 Apr 2017 11:45:24 +0200 Subject: [PATCH] Add TermsLookup to TermsQuery The TermsQuery was missing the TermsLookup mechanism, as described here: https://www.elastic.co/guide/en/elasticsearch/reference/5.3/query-dsl-terms-query.html#query-dsl-terms-lookup Close #500 --- search_queries_terms.go | 40 +++++++++++++------ search_queries_terms_test.go | 18 +++++++++ search_terms_lookup.go | 74 ++++++++++++++++++++++++++++++++++++ search_terms_lookup_test.go | 27 +++++++++++++ 4 files changed, 147 insertions(+), 12 deletions(-) create mode 100644 search_terms_lookup.go create mode 100644 search_terms_lookup_test.go diff --git a/search_queries_terms.go b/search_queries_terms.go index 6875ae49a..b958ccf8f 100644 --- a/search_queries_terms.go +++ b/search_queries_terms.go @@ -10,17 +10,17 @@ package elastic // For more details, see // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/query-dsl-terms-query.html type TermsQuery struct { - name string - values []interface{} - queryName string - boost *float64 + name string + values []interface{} + termsLookup *TermsLookup + queryName string + boost *float64 } // NewTermsQuery creates and initializes a new TermsQuery. func NewTermsQuery(name string, values ...interface{}) *TermsQuery { q := &TermsQuery{ - name: name, - values: make([]interface{}, 0), + name: name, } if len(values) > 0 { q.values = append(q.values, values...) @@ -28,6 +28,12 @@ func NewTermsQuery(name string, values ...interface{}) *TermsQuery { return q } +// TermsLookup adds terms lookup details to the query. +func (q *TermsQuery) TermsLookup(lookup *TermsLookup) *TermsQuery { + q.termsLookup = lookup + return q +} + // Boost sets the boost for this query. func (q *TermsQuery) Boost(boost float64) *TermsQuery { q.boost = &boost @@ -47,12 +53,22 @@ func (q *TermsQuery) Source() (interface{}, error) { source := make(map[string]interface{}) params := make(map[string]interface{}) source["terms"] = params - params[q.name] = q.values - if q.boost != nil { - params["boost"] = *q.boost - } - if q.queryName != "" { - params["_name"] = q.queryName + + if q.termsLookup != nil { + src, err := q.termsLookup.Source() + if err != nil { + return nil, err + } + params[q.name] = src + } else { + params[q.name] = q.values + if q.boost != nil { + params["boost"] = *q.boost + } + if q.queryName != "" { + params["_name"] = q.queryName + } } + return source, nil } diff --git a/search_queries_terms_test.go b/search_queries_terms_test.go index 8818de213..d22a966b4 100644 --- a/search_queries_terms_test.go +++ b/search_queries_terms_test.go @@ -26,6 +26,24 @@ func TestTermsQuery(t *testing.T) { } } +func TestTermsQueryWithTermsLookup(t *testing.T) { + q := NewTermsQuery("user"). + TermsLookup(NewTermsLookup().Index("users").Type("user").Id("2").Path("followers")) + src, err := q.Source() + 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 := `{"terms":{"user":{"id":"2","index":"users","path":"followers","type":"user"}}}` + if got != expected { + t.Errorf("expected\n%s\n,got:\n%s", expected, got) + } +} + func TestTermQuerysWithOptions(t *testing.T) { q := NewTermsQuery("user", "ki", "ko") q = q.Boost(2.79) diff --git a/search_terms_lookup.go b/search_terms_lookup.go new file mode 100644 index 000000000..e59e15c12 --- /dev/null +++ b/search_terms_lookup.go @@ -0,0 +1,74 @@ +// 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 + +// TermsLookup encapsulates the parameters needed to fetch terms. +// +// For more details, see +// https://www.elastic.co/guide/en/elasticsearch/reference/5.3/query-dsl-terms-query.html#query-dsl-terms-lookup. +type TermsLookup struct { + index string + typ string + id string + path string + routing string +} + +// NewTermsLookup creates and initializes a new TermsLookup. +func NewTermsLookup() *TermsLookup { + t := &TermsLookup{} + return t +} + +// Index name. +func (t *TermsLookup) Index(index string) *TermsLookup { + t.index = index + return t +} + +// Type name. +func (t *TermsLookup) Type(typ string) *TermsLookup { + t.typ = typ + return t +} + +// Id to look up. +func (t *TermsLookup) Id(id string) *TermsLookup { + t.id = id + return t +} + +// Path to use for lookup. +func (t *TermsLookup) Path(path string) *TermsLookup { + t.path = path + return t +} + +// Routing value. +func (t *TermsLookup) Routing(routing string) *TermsLookup { + t.routing = routing + return t +} + +// Source creates the JSON source of the builder. +func (t *TermsLookup) Source() (interface{}, error) { + src := make(map[string]interface{}) + if t.index != "" { + src["index"] = t.index + } + if t.typ != "" { + src["type"] = t.typ + } + if t.id != "" { + src["id"] = t.id + } + if t.path != "" { + src["path"] = t.path + } + if t.routing != "" { + src["routing"] = t.routing + } + return src, nil +} diff --git a/search_terms_lookup_test.go b/search_terms_lookup_test.go new file mode 100644 index 000000000..369f72346 --- /dev/null +++ b/search_terms_lookup_test.go @@ -0,0 +1,27 @@ +// 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 TestTermsLookup(t *testing.T) { + tl := NewTermsLookup().Index("users").Type("user").Id("2").Path("followers") + src, err := tl.Source() + 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 := `{"id":"2","index":"users","path":"followers","type":"user"}` + if got != expected { + t.Errorf("expected\n%s\n,got:\n%s", expected, got) + } +}