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
|
@ -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,
|
||||
})
|
||||
}
|
|
@ -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",
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
})
|
||||
}
|
|
@ -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",
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
})
|
||||
}
|
|
@ -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",
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
})
|
||||
}
|
|
@ -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…
Reference in New Issue