1// Copyright 2012-present Oliver Eilhard. All rights reserved. 2// Use of this source code is governed by a MIT-license. 3// See http://olivere.mit-license.org/license.txt for details. 4 5package elastic 6 7// MatchQuery is a family of queries that accepts text/numerics/dates, 8// analyzes them, and constructs a query. 9// 10// To create a new MatchQuery, use NewMatchQuery. To create specific types 11// of queries, e.g. a match_phrase query, use NewMatchPhrQuery(...).Type("phrase"), 12// or use one of the shortcuts e.g. NewMatchPhraseQuery(...). 13// 14// For more details, see 15// https://www.elastic.co/guide/en/elasticsearch/reference/5.2/query-dsl-match-query.html 16type MatchQuery struct { 17 name string 18 text interface{} 19 operator string // or / and 20 analyzer string 21 boost *float64 22 fuzziness string 23 prefixLength *int 24 maxExpansions *int 25 minimumShouldMatch string 26 fuzzyRewrite string 27 lenient *bool 28 fuzzyTranspositions *bool 29 zeroTermsQuery string 30 cutoffFrequency *float64 31 queryName string 32} 33 34// NewMatchQuery creates and initializes a new MatchQuery. 35func NewMatchQuery(name string, text interface{}) *MatchQuery { 36 return &MatchQuery{name: name, text: text} 37} 38 39// Operator sets the operator to use when using a boolean query. 40// Can be "AND" or "OR" (default). 41func (q *MatchQuery) Operator(operator string) *MatchQuery { 42 q.operator = operator 43 return q 44} 45 46// Analyzer explicitly sets the analyzer to use. It defaults to use explicit 47// mapping config for the field, or, if not set, the default search analyzer. 48func (q *MatchQuery) Analyzer(analyzer string) *MatchQuery { 49 q.analyzer = analyzer 50 return q 51} 52 53// Fuzziness sets the fuzziness when evaluated to a fuzzy query type. 54// Defaults to "AUTO". 55func (q *MatchQuery) Fuzziness(fuzziness string) *MatchQuery { 56 q.fuzziness = fuzziness 57 return q 58} 59 60// PrefixLength sets the length of a length of common (non-fuzzy) 61// prefix for fuzzy match queries. It must be non-negative. 62func (q *MatchQuery) PrefixLength(prefixLength int) *MatchQuery { 63 q.prefixLength = &prefixLength 64 return q 65} 66 67// MaxExpansions is used with fuzzy or prefix type queries. It specifies 68// the number of term expansions to use. It defaults to unbounded so that 69// its recommended to set it to a reasonable value for faster execution. 70func (q *MatchQuery) MaxExpansions(maxExpansions int) *MatchQuery { 71 q.maxExpansions = &maxExpansions 72 return q 73} 74 75// CutoffFrequency can be a value in [0..1] (or an absolute number >=1). 76// It represents the maximum treshold of a terms document frequency to be 77// considered a low frequency term. 78func (q *MatchQuery) CutoffFrequency(cutoff float64) *MatchQuery { 79 q.cutoffFrequency = &cutoff 80 return q 81} 82 83// MinimumShouldMatch sets the optional minimumShouldMatch value to 84// apply to the query. 85func (q *MatchQuery) MinimumShouldMatch(minimumShouldMatch string) *MatchQuery { 86 q.minimumShouldMatch = minimumShouldMatch 87 return q 88} 89 90// FuzzyRewrite sets the fuzzy_rewrite parameter controlling how the 91// fuzzy query will get rewritten. 92func (q *MatchQuery) FuzzyRewrite(fuzzyRewrite string) *MatchQuery { 93 q.fuzzyRewrite = fuzzyRewrite 94 return q 95} 96 97// FuzzyTranspositions sets whether transpositions are supported in 98// fuzzy queries. 99// 100// The default metric used by fuzzy queries to determine a match is 101// the Damerau-Levenshtein distance formula which supports transpositions. 102// Setting transposition to false will 103// * switch to classic Levenshtein distance. 104// * If not set, Damerau-Levenshtein distance metric will be used. 105func (q *MatchQuery) FuzzyTranspositions(fuzzyTranspositions bool) *MatchQuery { 106 q.fuzzyTranspositions = &fuzzyTranspositions 107 return q 108} 109 110// Lenient specifies whether format based failures will be ignored. 111func (q *MatchQuery) Lenient(lenient bool) *MatchQuery { 112 q.lenient = &lenient 113 return q 114} 115 116// ZeroTermsQuery can be "all" or "none". 117func (q *MatchQuery) ZeroTermsQuery(zeroTermsQuery string) *MatchQuery { 118 q.zeroTermsQuery = zeroTermsQuery 119 return q 120} 121 122// Boost sets the boost to apply to this query. 123func (q *MatchQuery) Boost(boost float64) *MatchQuery { 124 q.boost = &boost 125 return q 126} 127 128// QueryName sets the query name for the filter that can be used when 129// searching for matched filters per hit. 130func (q *MatchQuery) QueryName(queryName string) *MatchQuery { 131 q.queryName = queryName 132 return q 133} 134 135// Source returns JSON for the function score query. 136func (q *MatchQuery) Source() (interface{}, error) { 137 // {"match":{"name":{"query":"value","type":"boolean/phrase"}}} 138 source := make(map[string]interface{}) 139 140 match := make(map[string]interface{}) 141 source["match"] = match 142 143 query := make(map[string]interface{}) 144 match[q.name] = query 145 146 query["query"] = q.text 147 148 if q.operator != "" { 149 query["operator"] = q.operator 150 } 151 if q.analyzer != "" { 152 query["analyzer"] = q.analyzer 153 } 154 if q.fuzziness != "" { 155 query["fuzziness"] = q.fuzziness 156 } 157 if q.prefixLength != nil { 158 query["prefix_length"] = *q.prefixLength 159 } 160 if q.maxExpansions != nil { 161 query["max_expansions"] = *q.maxExpansions 162 } 163 if q.minimumShouldMatch != "" { 164 query["minimum_should_match"] = q.minimumShouldMatch 165 } 166 if q.fuzzyRewrite != "" { 167 query["fuzzy_rewrite"] = q.fuzzyRewrite 168 } 169 if q.lenient != nil { 170 query["lenient"] = *q.lenient 171 } 172 if q.fuzzyTranspositions != nil { 173 query["fuzzy_transpositions"] = *q.fuzzyTranspositions 174 } 175 if q.zeroTermsQuery != "" { 176 query["zero_terms_query"] = q.zeroTermsQuery 177 } 178 if q.cutoffFrequency != nil { 179 query["cutoff_frequency"] = q.cutoffFrequency 180 } 181 if q.boost != nil { 182 query["boost"] = *q.boost 183 } 184 if q.queryName != "" { 185 query["_name"] = q.queryName 186 } 187 188 return source, nil 189} 190