Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Match boolean prefix query #1497

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -333,6 +333,7 @@ Here are a few tips on how to get used to Elastic:
- [x] Inner hits
- Full text queries
- [x] Match Query
- [x] Match Boolean Prefix Query
- [x] Match Phrase Query
- [x] Match Phrase Prefix Query
- [x] Multi Match Query
Expand Down
129 changes: 129 additions & 0 deletions search_queries_match_bool_prefix.go
@@ -0,0 +1,129 @@
// Use of this source code is governed by a MIT-license.
// See http://olivere.mit-license.org/license.txt for details.

package elastic

// MatchBoolPrefixQuery query analyzes its input and constructs a bool query from the terms.
// Each term except the last is used in a term query. The last term is used in a prefix query.
//
// For more details, see
// https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-match-bool-prefix-query.html
type MatchBoolPrefixQuery struct {
name string
queryText interface{}
analyzer string
minimumShouldMatch string
operator string
fuzziness string
prefixLength *int
maxExpansions *int
fuzzyTranspositions *bool
fuzzyRewrite string
boost *float64
}

// NewMatchBoolPrefixQuery creates and initializes a new MatchBoolPrefixQuery.
func NewMatchBoolPrefixQuery(name string, queryText interface{}) *MatchBoolPrefixQuery {
return &MatchBoolPrefixQuery{name: name, queryText: queryText}
}

// Analyzer explicitly sets the analyzer to use. It defaults to use explicit
// mapping config for the field, or, if not set, the default search analyzer.
func (q *MatchBoolPrefixQuery) Analyzer(analyzer string) *MatchBoolPrefixQuery {
q.analyzer = analyzer
return q
}

// MinimumShouldMatch sets the optional minimumShouldMatch value to apply to the query.
func (q *MatchBoolPrefixQuery) MinimumShouldMatch(minimumShouldMatch string) *MatchBoolPrefixQuery {
q.minimumShouldMatch = minimumShouldMatch
return q
}

// Operator sets the operator to use when using a boolean query.
// Can be "AND" or "OR" (default).
func (q *MatchBoolPrefixQuery) Operator(operator string) *MatchBoolPrefixQuery {
q.operator = operator
return q
}

// Fuzziness sets the edit distance for fuzzy queries. Default is "AUTO".
func (q *MatchBoolPrefixQuery) Fuzziness(fuzziness string) *MatchBoolPrefixQuery {
q.fuzziness = fuzziness
return q
}

// PrefixLength is the number of beginning characters left unchanged for fuzzy matching. Defaults to 0.
func (q *MatchBoolPrefixQuery) PrefixLength(prefixLength int) *MatchBoolPrefixQuery {
q.prefixLength = &prefixLength
return q
}

// MaxExpansions sets the number of term expansions to use.
func (q *MatchBoolPrefixQuery) MaxExpansions(n int) *MatchBoolPrefixQuery {
q.maxExpansions = &n
return q
}

// FuzzyTranspositions if true, edits for fuzzy matching include transpositions of two adjacent
// characters (ab → ba). Defaults to true.
func (q *MatchBoolPrefixQuery) FuzzyTranspositions(fuzzyTranspositions bool) *MatchBoolPrefixQuery {
q.fuzzyTranspositions = &fuzzyTranspositions
return q
}

// FuzzyRewrite sets the fuzzy_rewrite parameter controlling how the
// fuzzy query will get rewritten.
func (q *MatchBoolPrefixQuery) FuzzyRewrite(fuzzyRewrite string) *MatchBoolPrefixQuery {
q.fuzzyRewrite = fuzzyRewrite
return q
}

// Boost sets the boost to apply to this query.
func (q *MatchBoolPrefixQuery) Boost(boost float64) *MatchBoolPrefixQuery {
q.boost = &boost
return q
}

// Source returns JSON for the function score query.
func (q *MatchBoolPrefixQuery) Source() (interface{}, error) {
source := make(map[string]interface{})

match := make(map[string]interface{})
source["match_bool_prefix"] = match

query := make(map[string]interface{})
match[q.name] = query

query["query"] = q.queryText

if q.analyzer != "" {
query["analyzer"] = q.analyzer
}
if q.minimumShouldMatch != "" {
query["minimum_should_match"] = q.minimumShouldMatch
}
if q.operator != "" {
query["operator"] = q.operator
}
if q.fuzziness != "" {
query["fuzziness"] = q.fuzziness
}
if q.prefixLength != nil {
query["prefix_length"] = *q.prefixLength
}
if q.maxExpansions != nil {
query["max_expansions"] = *q.maxExpansions
}
if q.fuzzyTranspositions != nil {
query["fuzzy_transpositions"] = *q.fuzzyTranspositions
}
if q.fuzzyRewrite != "" {
query["fuzzy_rewrite"] = q.fuzzyRewrite
}
if q.boost != nil {
query["boost"] = *q.boost
}

return source, nil
}
35 changes: 35 additions & 0 deletions search_queries_match_bool_prefix_test.go
@@ -0,0 +1,35 @@
// 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 TestMatchBoolPrefixQuery(t *testing.T) {
q := NewMatchBoolPrefixQuery("query_name", "this is a test").
Analyzer("custom_analyzer").
MinimumShouldMatch("75%").
Operator("AND").
Fuzziness("AUTO").
PrefixLength(1).
MaxExpansions(5).
FuzzyTranspositions(false).
FuzzyRewrite("constant_score").
Boost(0.3)
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 := `{"match_bool_prefix":{"query_name":{"analyzer":"custom_analyzer","boost":0.3,"fuzziness":"AUTO","fuzzy_rewrite":"constant_score","fuzzy_transpositions":false,"max_expansions":5,"minimum_should_match":"75%","operator":"AND","prefix_length":1,"query":"this is a test"}}}`
if got != expected {
t.Errorf("expected\n%s\n,got:\n%s", expected, got)
}
}