mirror of
https://github.com/pgsty/minio.git
synced 2026-08-11 08:43:28 +03:00
api: Implement bucket notification. (#2271)
* Implement basic S3 notifications through queues Supports multiple queues and three basic queue types: 1. NilQueue -- messages don't get sent anywhere 2. LogQueue -- messages get logged 3. AmqpQueue -- messages are sent to an AMQP queue * api: Implement bucket notification. Supports two different queue types - AMQP - ElasticSearch. * Add support for redis
This commit is contained in:
committed by
Anand Babu (AB) Periasamy
parent
f85d94288d
commit
f248089523
+275
@@ -0,0 +1,275 @@
|
||||
// Copyright 2012-2015 Oliver Eilhard. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-license.
|
||||
// See http://olivere.mit-license.org/license.txt for details.
|
||||
|
||||
package elastic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MultiMatchQuery builds on the MatchQuery to allow multi-field queries.
|
||||
//
|
||||
// For more details, see
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html
|
||||
type MultiMatchQuery struct {
|
||||
text interface{}
|
||||
fields []string
|
||||
fieldBoosts map[string]*float64
|
||||
typ string // best_fields, boolean, most_fields, cross_fields, phrase, phrase_prefix
|
||||
operator string // AND or OR
|
||||
analyzer string
|
||||
boost *float64
|
||||
slop *int
|
||||
fuzziness string
|
||||
prefixLength *int
|
||||
maxExpansions *int
|
||||
minimumShouldMatch string
|
||||
rewrite string
|
||||
fuzzyRewrite string
|
||||
tieBreaker *float64
|
||||
lenient *bool
|
||||
cutoffFrequency *float64
|
||||
zeroTermsQuery string
|
||||
queryName string
|
||||
}
|
||||
|
||||
// MultiMatchQuery creates and initializes a new MultiMatchQuery.
|
||||
func NewMultiMatchQuery(text interface{}, fields ...string) *MultiMatchQuery {
|
||||
q := &MultiMatchQuery{
|
||||
text: text,
|
||||
fields: make([]string, 0),
|
||||
fieldBoosts: make(map[string]*float64),
|
||||
}
|
||||
q.fields = append(q.fields, fields...)
|
||||
return q
|
||||
}
|
||||
|
||||
// Field adds a field to run the multi match against.
|
||||
func (q *MultiMatchQuery) Field(field string) *MultiMatchQuery {
|
||||
q.fields = append(q.fields, field)
|
||||
return q
|
||||
}
|
||||
|
||||
// FieldWithBoost adds a field to run the multi match against with a specific boost.
|
||||
func (q *MultiMatchQuery) FieldWithBoost(field string, boost float64) *MultiMatchQuery {
|
||||
q.fields = append(q.fields, field)
|
||||
q.fieldBoosts[field] = &boost
|
||||
return q
|
||||
}
|
||||
|
||||
// Type can be "best_fields", "boolean", "most_fields", "cross_fields",
|
||||
// "phrase", or "phrase_prefix".
|
||||
func (q *MultiMatchQuery) Type(typ string) *MultiMatchQuery {
|
||||
var zero = float64(0.0)
|
||||
var one = float64(1.0)
|
||||
|
||||
switch strings.ToLower(typ) {
|
||||
default: // best_fields / boolean
|
||||
q.typ = "best_fields"
|
||||
q.tieBreaker = &zero
|
||||
case "most_fields":
|
||||
q.typ = "most_fields"
|
||||
q.tieBreaker = &one
|
||||
case "cross_fields":
|
||||
q.typ = "cross_fields"
|
||||
q.tieBreaker = &zero
|
||||
case "phrase":
|
||||
q.typ = "phrase"
|
||||
q.tieBreaker = &zero
|
||||
case "phrase_prefix":
|
||||
q.typ = "phrase_prefix"
|
||||
q.tieBreaker = &zero
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// Operator sets the operator to use when using boolean query.
|
||||
// It can be either AND or OR (default).
|
||||
func (q *MultiMatchQuery) Operator(operator string) *MultiMatchQuery {
|
||||
q.operator = operator
|
||||
return q
|
||||
}
|
||||
|
||||
// Analyzer sets the analyzer to use explicitly. It defaults to use explicit
|
||||
// mapping config for the field, or, if not set, the default search analyzer.
|
||||
func (q *MultiMatchQuery) Analyzer(analyzer string) *MultiMatchQuery {
|
||||
q.analyzer = analyzer
|
||||
return q
|
||||
}
|
||||
|
||||
// Boost sets the boost for this query.
|
||||
func (q *MultiMatchQuery) Boost(boost float64) *MultiMatchQuery {
|
||||
q.boost = &boost
|
||||
return q
|
||||
}
|
||||
|
||||
// Slop sets the phrase slop if evaluated to a phrase query type.
|
||||
func (q *MultiMatchQuery) Slop(slop int) *MultiMatchQuery {
|
||||
q.slop = &slop
|
||||
return q
|
||||
}
|
||||
|
||||
// Fuzziness sets the fuzziness used when evaluated to a fuzzy query type.
|
||||
// It defaults to "AUTO".
|
||||
func (q *MultiMatchQuery) Fuzziness(fuzziness string) *MultiMatchQuery {
|
||||
q.fuzziness = fuzziness
|
||||
return q
|
||||
}
|
||||
|
||||
// PrefixLength for the fuzzy process.
|
||||
func (q *MultiMatchQuery) PrefixLength(prefixLength int) *MultiMatchQuery {
|
||||
q.prefixLength = &prefixLength
|
||||
return q
|
||||
}
|
||||
|
||||
// MaxExpansions is the number of term expansions to use when using fuzzy
|
||||
// or prefix type query. It defaults to unbounded so it's recommended
|
||||
// to set it to a reasonable value for faster execution.
|
||||
func (q *MultiMatchQuery) MaxExpansions(maxExpansions int) *MultiMatchQuery {
|
||||
q.maxExpansions = &maxExpansions
|
||||
return q
|
||||
}
|
||||
|
||||
// MinimumShouldMatch represents the minimum number of optional should clauses
|
||||
// to match.
|
||||
func (q *MultiMatchQuery) MinimumShouldMatch(minimumShouldMatch string) *MultiMatchQuery {
|
||||
q.minimumShouldMatch = minimumShouldMatch
|
||||
return q
|
||||
}
|
||||
|
||||
func (q *MultiMatchQuery) Rewrite(rewrite string) *MultiMatchQuery {
|
||||
q.rewrite = rewrite
|
||||
return q
|
||||
}
|
||||
|
||||
func (q *MultiMatchQuery) FuzzyRewrite(fuzzyRewrite string) *MultiMatchQuery {
|
||||
q.fuzzyRewrite = fuzzyRewrite
|
||||
return q
|
||||
}
|
||||
|
||||
// TieBreaker for "best-match" disjunction queries (OR queries).
|
||||
// The tie breaker capability allows documents that match more than one
|
||||
// query clause (in this case on more than one field) to be scored better
|
||||
// than documents that match only the best of the fields, without confusing
|
||||
// this with the better case of two distinct matches in the multiple fields.
|
||||
//
|
||||
// A tie-breaker value of 1.0 is interpreted as a signal to score queries as
|
||||
// "most-match" queries where all matching query clauses are considered for scoring.
|
||||
func (q *MultiMatchQuery) TieBreaker(tieBreaker float64) *MultiMatchQuery {
|
||||
q.tieBreaker = &tieBreaker
|
||||
return q
|
||||
}
|
||||
|
||||
// Lenient indicates whether format based failures will be ignored.
|
||||
func (q *MultiMatchQuery) Lenient(lenient bool) *MultiMatchQuery {
|
||||
q.lenient = &lenient
|
||||
return q
|
||||
}
|
||||
|
||||
// CutoffFrequency sets a cutoff value in [0..1] (or absolute number >=1)
|
||||
// representing the maximum threshold of a terms document frequency to be
|
||||
// considered a low frequency term.
|
||||
func (q *MultiMatchQuery) CutoffFrequency(cutoff float64) *MultiMatchQuery {
|
||||
q.cutoffFrequency = &cutoff
|
||||
return q
|
||||
}
|
||||
|
||||
// ZeroTermsQuery can be "all" or "none".
|
||||
func (q *MultiMatchQuery) ZeroTermsQuery(zeroTermsQuery string) *MultiMatchQuery {
|
||||
q.zeroTermsQuery = zeroTermsQuery
|
||||
return q
|
||||
}
|
||||
|
||||
// QueryName sets the query name for the filter that can be used when
|
||||
// searching for matched filters per hit.
|
||||
func (q *MultiMatchQuery) QueryName(queryName string) *MultiMatchQuery {
|
||||
q.queryName = queryName
|
||||
return q
|
||||
}
|
||||
|
||||
// Source returns JSON for the query.
|
||||
func (q *MultiMatchQuery) Source() (interface{}, error) {
|
||||
//
|
||||
// {
|
||||
// "multi_match" : {
|
||||
// "query" : "this is a test",
|
||||
// "fields" : [ "subject", "message" ]
|
||||
// }
|
||||
// }
|
||||
|
||||
source := make(map[string]interface{})
|
||||
|
||||
multiMatch := make(map[string]interface{})
|
||||
source["multi_match"] = multiMatch
|
||||
|
||||
multiMatch["query"] = q.text
|
||||
|
||||
if len(q.fields) > 0 {
|
||||
fields := make([]string, 0)
|
||||
for _, field := range q.fields {
|
||||
if boost, found := q.fieldBoosts[field]; found {
|
||||
if boost != nil {
|
||||
fields = append(fields, fmt.Sprintf("%s^%f", field, *boost))
|
||||
} else {
|
||||
fields = append(fields, field)
|
||||
}
|
||||
} else {
|
||||
fields = append(fields, field)
|
||||
}
|
||||
}
|
||||
multiMatch["fields"] = fields
|
||||
}
|
||||
|
||||
if q.typ != "" {
|
||||
multiMatch["type"] = q.typ
|
||||
}
|
||||
|
||||
if q.operator != "" {
|
||||
multiMatch["operator"] = q.operator
|
||||
}
|
||||
if q.analyzer != "" {
|
||||
multiMatch["analyzer"] = q.analyzer
|
||||
}
|
||||
if q.boost != nil {
|
||||
multiMatch["boost"] = *q.boost
|
||||
}
|
||||
if q.slop != nil {
|
||||
multiMatch["slop"] = *q.slop
|
||||
}
|
||||
if q.fuzziness != "" {
|
||||
multiMatch["fuzziness"] = q.fuzziness
|
||||
}
|
||||
if q.prefixLength != nil {
|
||||
multiMatch["prefix_length"] = *q.prefixLength
|
||||
}
|
||||
if q.maxExpansions != nil {
|
||||
multiMatch["max_expansions"] = *q.maxExpansions
|
||||
}
|
||||
if q.minimumShouldMatch != "" {
|
||||
multiMatch["minimum_should_match"] = q.minimumShouldMatch
|
||||
}
|
||||
if q.rewrite != "" {
|
||||
multiMatch["rewrite"] = q.rewrite
|
||||
}
|
||||
if q.fuzzyRewrite != "" {
|
||||
multiMatch["fuzzy_rewrite"] = q.fuzzyRewrite
|
||||
}
|
||||
if q.tieBreaker != nil {
|
||||
multiMatch["tie_breaker"] = *q.tieBreaker
|
||||
}
|
||||
if q.lenient != nil {
|
||||
multiMatch["lenient"] = *q.lenient
|
||||
}
|
||||
if q.cutoffFrequency != nil {
|
||||
multiMatch["cutoff_frequency"] = *q.cutoffFrequency
|
||||
}
|
||||
if q.zeroTermsQuery != "" {
|
||||
multiMatch["zero_terms_query"] = q.zeroTermsQuery
|
||||
}
|
||||
if q.queryName != "" {
|
||||
multiMatch["_name"] = q.queryName
|
||||
}
|
||||
return source, nil
|
||||
}
|
||||
Reference in New Issue
Block a user