Add support for compound queries
This commit adds support for the compound queries "bool", "boosting",
"constant_score" and "dis_max". The "function_score" query is not
supported yet.
Compound queries are simple. They act just like simple queries, except
that they are recursive, wrapping other simple/compound queries.
For example:
    esquery.Bool().
        Must(Term("user", "kimchy"), Term("author", "kimchy")).
        Filter(Term("tag", "tech"))
			
			
This commit is contained in:
		
							parent
							
								
									9ef149ec94
								
							
						
					
					
						commit
						6c8e71c188
					
				
							
								
								
									
										61
									
								
								boolean.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								boolean.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "encoding/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Boolean Queries
 | 
				
			||||||
 | 
					 * https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BoolQuery struct {
 | 
				
			||||||
 | 
						params boolQueryParams
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type boolQueryParams struct {
 | 
				
			||||||
 | 
						Must               []json.Marshaler `json:"must,omitempty"`
 | 
				
			||||||
 | 
						Filter             []json.Marshaler `json:"filter,omitempty"`
 | 
				
			||||||
 | 
						MustNot            []json.Marshaler `json:"must_not,omitempty"`
 | 
				
			||||||
 | 
						Should             []json.Marshaler `json:"should,omitempty"`
 | 
				
			||||||
 | 
						MinimumShouldMatch int16            `json:"minimum_should_match,omitempty"`
 | 
				
			||||||
 | 
						Boost              float32          `json:"boost,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Bool() *BoolQuery {
 | 
				
			||||||
 | 
						return &BoolQuery{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoolQuery) Must(must ...json.Marshaler) *BoolQuery {
 | 
				
			||||||
 | 
						q.params.Must = append(q.params.Must, must...)
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoolQuery) Filter(filter ...json.Marshaler) *BoolQuery {
 | 
				
			||||||
 | 
						q.params.Filter = append(q.params.Filter, filter...)
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoolQuery) MustNot(mustnot ...json.Marshaler) *BoolQuery {
 | 
				
			||||||
 | 
						q.params.MustNot = append(q.params.MustNot, mustnot...)
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoolQuery) Should(should ...json.Marshaler) *BoolQuery {
 | 
				
			||||||
 | 
						q.params.Should = append(q.params.Should, should...)
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoolQuery) MinimumShouldMatch(val int16) *BoolQuery {
 | 
				
			||||||
 | 
						q.params.MinimumShouldMatch = val
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoolQuery) Boost(val float32) *BoolQuery {
 | 
				
			||||||
 | 
						q.params.Boost = val
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q BoolQuery) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.Marshal(map[string]boolQueryParams{
 | 
				
			||||||
 | 
							"bool": q.params,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								boolean_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								boolean_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestBool(t *testing.T) {
 | 
				
			||||||
 | 
						runTests(t, []queryTest{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"bool with only a simple must",
 | 
				
			||||||
 | 
								Bool().Must(Term("tag", "tech")),
 | 
				
			||||||
 | 
								"{\"bool\":{\"must\":[{\"term\":{\"tag\":{\"value\":\"tech\"}}}]}}\n",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"bool which must match_all and filter",
 | 
				
			||||||
 | 
								Bool().Must(MatchAll()).Filter(Term("status", "active")),
 | 
				
			||||||
 | 
								"{\"bool\":{\"must\":[{\"match_all\":{}}],\"filter\":[{\"term\":{\"status\":{\"value\":\"active\"}}}]}}\n",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"bool with a lot of stuff",
 | 
				
			||||||
 | 
								Bool().
 | 
				
			||||||
 | 
									Must(Term("user", "kimchy")).
 | 
				
			||||||
 | 
									Filter(Term("tag", "tech")).
 | 
				
			||||||
 | 
									MustNot(Range("age").Gte(10).Lte(20)).
 | 
				
			||||||
 | 
									Should(Term("tag", "wow"), Term("tag", "elasticsearch")).
 | 
				
			||||||
 | 
									MinimumShouldMatch(1).
 | 
				
			||||||
 | 
									Boost(1.1),
 | 
				
			||||||
 | 
								"{\"bool\":{\"must\":[{\"term\":{\"user\":{\"value\":\"kimchy\"}}}],\"filter\":[{\"term\":{\"tag\":{\"value\":\"tech\"}}}],\"must_not\":[{\"range\":{\"age\":{\"gte\":10,\"lte\":20}}}],\"should\":[{\"term\":{\"tag\":{\"value\":\"wow\"}}},{\"term\":{\"tag\":{\"value\":\"elasticsearch\"}}}],\"minimum_should_match\":1,\"boost\":1.1}}\n",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								boosting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								boosting.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "encoding/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Boosting Queries
 | 
				
			||||||
 | 
					 * https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BoostingQuery struct {
 | 
				
			||||||
 | 
						params boostingQueryParams
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type boostingQueryParams struct {
 | 
				
			||||||
 | 
						Positive      json.Marshaler `json:"positive"`
 | 
				
			||||||
 | 
						Negative      json.Marshaler `json:"negative"`
 | 
				
			||||||
 | 
						NegativeBoost float32        `json:"negative_boost"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Boosting() *BoostingQuery {
 | 
				
			||||||
 | 
						return &BoostingQuery{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoostingQuery) Positive(p json.Marshaler) *BoostingQuery {
 | 
				
			||||||
 | 
						q.params.Positive = p
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoostingQuery) Negative(p json.Marshaler) *BoostingQuery {
 | 
				
			||||||
 | 
						q.params.Negative = p
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoostingQuery) NegativeBoost(b float32) *BoostingQuery {
 | 
				
			||||||
 | 
						q.params.NegativeBoost = b
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *BoostingQuery) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.Marshal(map[string]boostingQueryParams{
 | 
				
			||||||
 | 
							"boosting": q.params,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								boosting_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								boosting_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestBoost(t *testing.T) {
 | 
				
			||||||
 | 
						runTests(t, []queryTest{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"boosting query",
 | 
				
			||||||
 | 
								Boosting().
 | 
				
			||||||
 | 
									Positive(Term("text", "apple")).
 | 
				
			||||||
 | 
									Negative(Term("text", "pie tart")).
 | 
				
			||||||
 | 
									NegativeBoost(0.5),
 | 
				
			||||||
 | 
								"{\"boosting\":{\"positive\":{\"term\":{\"text\":{\"value\":\"apple\"}}},\"negative\":{\"term\":{\"text\":{\"value\":\"pie tart\"}}},\"negative_boost\":0.5}}\n",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								constant_score.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								constant_score.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "encoding/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ConstantScoreQuery struct {
 | 
				
			||||||
 | 
						params constantScoreParams
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type constantScoreParams struct {
 | 
				
			||||||
 | 
						Filter json.Marshaler `json:"filter"`
 | 
				
			||||||
 | 
						Boost  float32        `json:"boost,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ConstantScore(filter json.Marshaler) *ConstantScoreQuery {
 | 
				
			||||||
 | 
						return &ConstantScoreQuery{
 | 
				
			||||||
 | 
							params: constantScoreParams{Filter: filter},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *ConstantScoreQuery) Boost(b float32) *ConstantScoreQuery {
 | 
				
			||||||
 | 
						q.params.Boost = b
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q ConstantScoreQuery) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.Marshal(map[string]constantScoreParams{
 | 
				
			||||||
 | 
							"constant_score": q.params,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								constant_score_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								constant_score_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestConstantScore(t *testing.T) {
 | 
				
			||||||
 | 
						runTests(t, []queryTest{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"constant_score query without boost",
 | 
				
			||||||
 | 
								ConstantScore(Term("user", "kimchy")),
 | 
				
			||||||
 | 
								"{\"constant_score\":{\"filter\":{\"term\":{\"user\":{\"value\":\"kimchy\"}}}}}\n",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"constant_score query with boost",
 | 
				
			||||||
 | 
								ConstantScore(Term("user", "kimchy")).Boost(2.2),
 | 
				
			||||||
 | 
								"{\"constant_score\":{\"filter\":{\"term\":{\"user\":{\"value\":\"kimchy\"}}},\"boost\":2.2}}\n",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								dis_max.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								dis_max.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "encoding/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DisMaxQuery struct {
 | 
				
			||||||
 | 
						params disMaxParams
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type disMaxParams struct {
 | 
				
			||||||
 | 
						Queries    []json.Marshaler `json:"queries"`
 | 
				
			||||||
 | 
						TieBreaker float32          `json:"tie_breaker,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DisMax(queries ...json.Marshaler) *DisMaxQuery {
 | 
				
			||||||
 | 
						return &DisMaxQuery{
 | 
				
			||||||
 | 
							params: disMaxParams{
 | 
				
			||||||
 | 
								Queries: queries,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *DisMaxQuery) TieBreaker(b float32) *DisMaxQuery {
 | 
				
			||||||
 | 
						q.params.TieBreaker = b
 | 
				
			||||||
 | 
						return q
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q DisMaxQuery) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.Marshal(map[string]disMaxParams{
 | 
				
			||||||
 | 
							"dis_max": q.params,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								dis_max_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								dis_max_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					package esquery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestDisMax(t *testing.T) {
 | 
				
			||||||
 | 
						runTests(t, []queryTest{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"dis_max",
 | 
				
			||||||
 | 
								DisMax(Term("title", "Quick pets"), Term("body", "Quick pets")).TieBreaker(0.7),
 | 
				
			||||||
 | 
								"{\"dis_max\":{\"queries\":[{\"term\":{\"title\":{\"value\":\"Quick pets\"}}},{\"term\":{\"body\":{\"value\":\"Quick pets\"}}}],\"tie_breaker\":0.7}}\n",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user