Skip to content

Commit

Permalink
Add TermsLookup to TermsQuery
Browse files Browse the repository at this point in the history
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
  • Loading branch information
olivere committed Apr 10, 2017
1 parent 7169c87 commit f698dfe
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 12 deletions.
40 changes: 28 additions & 12 deletions search_queries_terms.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,30 @@ 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...)
}
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
Expand All @@ -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
}
18 changes: 18 additions & 0 deletions search_queries_terms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
74 changes: 74 additions & 0 deletions search_terms_lookup.go
Original file line number Diff line number Diff line change
@@ -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
}
27 changes: 27 additions & 0 deletions search_terms_lookup_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit f698dfe

Please sign in to comment.