254 lines
7.7 KiB
Go
254 lines
7.7 KiB
Go
package esquery
|
|
|
|
import (
|
|
"github.com/fatih/structs"
|
|
)
|
|
|
|
type matchType uint8
|
|
|
|
const (
|
|
// TypeMatch denotes a query of type "match"
|
|
TypeMatch matchType = iota
|
|
|
|
// TypeMatchBool denotes a query of type "match_bool_prefix"
|
|
TypeMatchBoolPrefix
|
|
|
|
// TypeMatchPhrase denotes a query of type "match_phrase"
|
|
TypeMatchPhrase
|
|
|
|
// TypeMatchPhrasePrefix denotes a query of type "match_phrase_prefix"
|
|
TypeMatchPhrasePrefix
|
|
)
|
|
|
|
// MatchQuery represents a query of type "match", "match_bool_prefix",
|
|
// "match_phrase" and "match_phrase_prefix". While all four share the same
|
|
// general structure, they don't necessarily support all the same options. The
|
|
// library does not attempt to verify provided options are supported.
|
|
// See the ElasticSearch documentation for more information:
|
|
// - https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
|
|
// - https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-bool-prefix-query.html
|
|
// - https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html
|
|
// - https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase-prefix.html
|
|
type MatchQuery struct {
|
|
field string
|
|
mType matchType
|
|
params matchParams
|
|
}
|
|
|
|
// Map returns a map representation of the query, thus implementing the
|
|
// Mappable interface.
|
|
func (q *MatchQuery) Map() map[string]interface{} {
|
|
var mType string
|
|
switch q.mType {
|
|
case TypeMatch:
|
|
mType = "match"
|
|
case TypeMatchBoolPrefix:
|
|
mType = "match_bool_prefix"
|
|
case TypeMatchPhrase:
|
|
mType = "match_phrase"
|
|
case TypeMatchPhrasePrefix:
|
|
mType = "match_phrase_prefix"
|
|
}
|
|
|
|
return map[string]interface{}{
|
|
mType: map[string]interface{}{
|
|
q.field: structs.Map(q.params),
|
|
},
|
|
}
|
|
}
|
|
|
|
type matchParams struct {
|
|
Qry interface{} `structs:"query"`
|
|
Anl string `structs:"analyzer,omitempty"`
|
|
AutoGenerate *bool `structs:"auto_generate_synonyms_phrase_query,omitempty"`
|
|
Fuzz string `structs:"fuzziness,omitempty"`
|
|
MaxExp uint16 `structs:"max_expansions,omitempty"`
|
|
PrefLen uint16 `structs:"prefix_length,omitempty"`
|
|
Trans *bool `structs:"transpositions,omitempty"`
|
|
FuzzyRw string `structs:"fuzzy_rewrite,omitempty"`
|
|
Lent bool `structs:"lenient,omitempty"`
|
|
Op MatchOperator `structs:"operator,string,omitempty"`
|
|
MinMatch string `structs:"minimum_should_match,omitempty"`
|
|
ZeroTerms ZeroTerms `structs:"zero_terms_query,string,omitempty"`
|
|
Slp uint16 `structs:"slop,omitempty"` // only relevant for match_phrase query
|
|
}
|
|
|
|
// Match creates a new query of type "match" with the provided field name.
|
|
// A comparison value can optionally be provided to quickly create a simple
|
|
// query such as { "match": { "message": "this is a test" } }
|
|
func Match(fieldName string, simpleQuery ...interface{}) *MatchQuery {
|
|
return newMatch(TypeMatch, fieldName, simpleQuery...)
|
|
}
|
|
|
|
// MatchBoolPrefix creates a new query of type "match_bool_prefix" with the
|
|
// provided field name. A comparison value can optionally be provided to quickly
|
|
// create a simple query such as { "match": { "message": "this is a test" } }
|
|
func MatchBoolPrefix(fieldName string, simpleQuery ...interface{}) *MatchQuery {
|
|
return newMatch(TypeMatchBoolPrefix, fieldName, simpleQuery...)
|
|
}
|
|
|
|
// MatchPhrase creates a new query of type "match_phrase" with the
|
|
// provided field name. A comparison value can optionally be provided to quickly
|
|
// create a simple query such as { "match": { "message": "this is a test" } }
|
|
func MatchPhrase(fieldName string, simpleQuery ...interface{}) *MatchQuery {
|
|
return newMatch(TypeMatchPhrase, fieldName, simpleQuery...)
|
|
}
|
|
|
|
// MatchPhrasePrefix creates a new query of type "match_phrase_prefix" with the
|
|
// provided field name. A comparison value can optionally be provided to quickly
|
|
// create a simple query such as { "match": { "message": "this is a test" } }
|
|
func MatchPhrasePrefix(fieldName string, simpleQuery ...interface{}) *MatchQuery {
|
|
return newMatch(TypeMatchPhrasePrefix, fieldName, simpleQuery...)
|
|
}
|
|
|
|
func newMatch(mType matchType, fieldName string, simpleQuery ...interface{}) *MatchQuery {
|
|
var qry interface{}
|
|
if len(simpleQuery) > 0 {
|
|
qry = simpleQuery[len(simpleQuery)-1]
|
|
}
|
|
|
|
return &MatchQuery{
|
|
field: fieldName,
|
|
mType: mType,
|
|
params: matchParams{
|
|
Qry: qry,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Query sets the data to find in the query's field (it is the "query" component
|
|
// of the query).
|
|
func (q *MatchQuery) Query(data interface{}) *MatchQuery {
|
|
q.params.Qry = data
|
|
return q
|
|
}
|
|
|
|
// Analyzer sets the analyzer used to convert the text in the "query" value into
|
|
// tokens.
|
|
func (q *MatchQuery) Analyzer(a string) *MatchQuery {
|
|
q.params.Anl = a
|
|
return q
|
|
}
|
|
|
|
// AutoGenerateSynonymsPhraseQuery sets the "auto_generate_synonyms_phrase_query"
|
|
// boolean.
|
|
func (q *MatchQuery) AutoGenerateSynonymsPhraseQuery(b bool) *MatchQuery {
|
|
q.params.AutoGenerate = &b
|
|
return q
|
|
}
|
|
|
|
// Fuzziness set the maximum edit distance allowed for matching.
|
|
func (q *MatchQuery) Fuzziness(f string) *MatchQuery {
|
|
q.params.Fuzz = f
|
|
return q
|
|
}
|
|
|
|
// MaxExpansions sets the maximum number of terms to which the query will expand.
|
|
func (q *MatchQuery) MaxExpansions(e uint16) *MatchQuery {
|
|
q.params.MaxExp = e
|
|
return q
|
|
}
|
|
|
|
// PrefixLength sets the number of beginning characters left unchanged for fuzzy
|
|
// matching.
|
|
func (q *MatchQuery) PrefixLength(l uint16) *MatchQuery {
|
|
q.params.PrefLen = l
|
|
return q
|
|
}
|
|
|
|
// Transpositions sets whether edits for fuzzy matching include transpositions
|
|
// of two adjacent characters.
|
|
func (q *MatchQuery) Transpositions(b bool) *MatchQuery {
|
|
q.params.Trans = &b
|
|
return q
|
|
}
|
|
|
|
// FuzzyRewrite sets the method used to rewrite the query.
|
|
func (q *MatchQuery) FuzzyRewrite(s string) *MatchQuery {
|
|
q.params.FuzzyRw = s
|
|
return q
|
|
}
|
|
|
|
// Lenient sets whether format-based errors should be ignored.
|
|
func (q *MatchQuery) Lenient(b bool) *MatchQuery {
|
|
q.params.Lent = b
|
|
return q
|
|
}
|
|
|
|
// Operator sets the boolean logic used to interpret text in the query value.
|
|
func (q *MatchQuery) Operator(op MatchOperator) *MatchQuery {
|
|
q.params.Op = op
|
|
return q
|
|
}
|
|
|
|
// MinimumShouldMatch sets the minimum number of clauses that must match for a
|
|
// document to be returned.
|
|
func (q *MatchQuery) MinimumShouldMatch(s string) *MatchQuery {
|
|
q.params.MinMatch = s
|
|
return q
|
|
}
|
|
|
|
// Slop sets the maximum number of positions allowed between matching tokens.
|
|
func (q *MatchQuery) Slop(n uint16) *MatchQuery {
|
|
q.params.Slp = n
|
|
return q
|
|
}
|
|
|
|
// ZeroTermsQuery sets the "zero_terms_query" option to use. This indicates
|
|
// whether no documents are returned if the analyzer removes all tokens, such as
|
|
// when using a stop filter.
|
|
func (q *MatchQuery) ZeroTermsQuery(s ZeroTerms) *MatchQuery {
|
|
q.params.ZeroTerms = s
|
|
return q
|
|
}
|
|
|
|
// MatchOperator is an enumeration type representing supported values for a
|
|
// match query's "operator" parameter.
|
|
type MatchOperator uint8
|
|
|
|
const (
|
|
// OperatorOr is the "or" operator
|
|
OperatorOr MatchOperator = iota
|
|
|
|
// OperatorAnd is the "and" operator
|
|
OperatorAnd
|
|
)
|
|
|
|
// String returns a string representation of the match operator, as known to
|
|
// ElasticSearch.
|
|
func (a MatchOperator) String() string {
|
|
switch a {
|
|
case OperatorOr:
|
|
return "OR"
|
|
case OperatorAnd:
|
|
return "AND"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// ZeroTerms is an enumeration type representing supported values for a match
|
|
// query's "zero_terms_query" parameter.
|
|
type ZeroTerms uint8
|
|
|
|
const (
|
|
// ZeroTermsNone is the "none" value
|
|
ZeroTermsNone ZeroTerms = iota
|
|
|
|
// ZeroTermsAll is the "all" value
|
|
ZeroTermsAll
|
|
)
|
|
|
|
// String returns a string representation of the zero_terms_query parameter, as
|
|
// known to ElasticSearch.
|
|
func (a ZeroTerms) String() string {
|
|
switch a {
|
|
case ZeroTermsNone:
|
|
return "none"
|
|
case ZeroTermsAll:
|
|
return "all"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|