filter

package
v1.0.0-beta.43 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2023 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EQ  = "$eq"
	GT  = "$gt"
	LT  = "$lt"
	GTE = "$gte"
	LTE = "$lte"
)

Variables

This section is empty.

Functions

func None

func None(reqFilter []byte) bool

Types

type AndFilter

type AndFilter struct {
	// contains filtered or unexported fields
}

AndFilter performs a logical AND operation on an array of two or more expressions. The and filter looks like this, {"$and": [{"f1":1}, {"f2": 3}....]} It can be nested i.e. a top level $and can have multiple nested $and/$or.

func NewAndFilter

func NewAndFilter(filter []Filter) (*AndFilter, error)

func (*AndFilter) GetFilters

func (a *AndFilter) GetFilters() []Filter

GetFilters returns all the nested filters for AndFilter.

func (*AndFilter) IsIndexed

func (a *AndFilter) IsIndexed() bool

func (*AndFilter) Matches

func (a *AndFilter) Matches(doc []byte) bool

Matches returns true if the input doc matches this filter.

func (*AndFilter) MatchesDoc

func (a *AndFilter) MatchesDoc(doc map[string]interface{}) bool

func (*AndFilter) String

func (a *AndFilter) String() string

String a helpful method for logging.

func (*AndFilter) ToSearchFilter

func (a *AndFilter) ToSearchFilter() []string

func (*AndFilter) Type

func (a *AndFilter) Type() LogicalOP

type EmptyFilter

type EmptyFilter struct{}

func (*EmptyFilter) IsIndexed

func (f *EmptyFilter) IsIndexed() bool

func (*EmptyFilter) Matches

func (f *EmptyFilter) Matches(_ []byte) bool

func (*EmptyFilter) MatchesDoc

func (f *EmptyFilter) MatchesDoc(_ map[string]interface{}) bool

func (*EmptyFilter) ToSearchFilter

func (f *EmptyFilter) ToSearchFilter() []string

type EqualityMatcher

type EqualityMatcher struct {
	Value value.Value
}

EqualityMatcher implements "$eq" operand.

func NewEqualityMatcher

func NewEqualityMatcher(v value.Value) *EqualityMatcher

NewEqualityMatcher returns EqualityMatcher object.

func (*EqualityMatcher) GetValue

func (e *EqualityMatcher) GetValue() value.Value

func (*EqualityMatcher) Matches

func (e *EqualityMatcher) Matches(input value.Value) bool

func (*EqualityMatcher) String

func (e *EqualityMatcher) String() string

func (*EqualityMatcher) Type

func (e *EqualityMatcher) Type() string

type Factory

type Factory struct {
	// contains filtered or unexported fields
}

func NewFactory

func NewFactory(fields []*schema.QueryableField, collation *value.Collation) *Factory

func (*Factory) Factorize

func (factory *Factory) Factorize(reqFilter []byte) ([]Filter, error)

func (*Factory) ParseSelector

func (factory *Factory) ParseSelector(k []byte, v []byte, dataType jsonparser.ValueType) (Filter, error)

ParseSelector is a short-circuit for Selector i.e. when we know the filter passed is not logical then we directly call this because if it is not logical then it is simply a Selector filter.

func (*Factory) UnmarshalAnd

func (factory *Factory) UnmarshalAnd(input jsoniter.RawMessage) (Filter, error)

func (*Factory) UnmarshalFilter

func (factory *Factory) UnmarshalFilter(input jsoniter.RawMessage) (expression.Expr, error)

func (*Factory) UnmarshalOr

func (factory *Factory) UnmarshalOr(input jsoniter.RawMessage) (Filter, error)

func (*Factory) WrappedFilter

func (factory *Factory) WrappedFilter(reqFilter []byte) (*WrappedFilter, error)

type Filter

type Filter interface {
	// Matches returns true if the input doc passes the filter, otherwise false
	Matches(doc []byte) bool
	// MatchesDoc similar to Matches but used when document is already parsed
	MatchesDoc(doc map[string]interface{}) bool
	ToSearchFilter() []string
	// IsIndexed to let caller knows if there is any non-indexed field in the query. This
	// will trigger full scan.
	IsIndexed() bool
}

A Filter represents a query filter that can have any multiple conditions, logical filtering, nested conditions, etc. On a high level, a filter from a user query will map like this

{Selector} --> Filter with a single condition
{Selector, Selector, LogicalOperator} --> Filter with two condition and a logicalOperator
{Selector, LogicalOperator} --> Filter with single condition and a logicalOperator
and so on...

The JSON representation for these filters will look like below, "filter: {"f1": 10} "filter": [{"f1": 10}, {"f2": {"$gt": 10}}] "filter": [{"f1": 10}, {"f2": 10}, {"$or": [{"f3": 20}, {"$and": [{"f4":5}, {"f5": 6}]}]}]

The default rule applied between filters are "$and and the default selector is "$eq".

type GreaterThanEqMatcher

type GreaterThanEqMatcher struct {
	Value value.Value
}

GreaterThanEqMatcher implements "$gte" operand.

func (*GreaterThanEqMatcher) GetValue

func (g *GreaterThanEqMatcher) GetValue() value.Value

func (*GreaterThanEqMatcher) Matches

func (g *GreaterThanEqMatcher) Matches(input value.Value) bool

func (*GreaterThanEqMatcher) String

func (g *GreaterThanEqMatcher) String() string

func (*GreaterThanEqMatcher) Type

func (g *GreaterThanEqMatcher) Type() string

type GreaterThanMatcher

type GreaterThanMatcher struct {
	Value value.Value
}

GreaterThanMatcher implements "$gt" operand.

func (*GreaterThanMatcher) GetValue

func (g *GreaterThanMatcher) GetValue() value.Value

func (*GreaterThanMatcher) Matches

func (g *GreaterThanMatcher) Matches(input value.Value) bool

func (*GreaterThanMatcher) String

func (g *GreaterThanMatcher) String() string

func (*GreaterThanMatcher) Type

func (g *GreaterThanMatcher) Type() string

type KeyBuilder

type KeyBuilder struct {
	// contains filtered or unexported fields
}

KeyBuilder is responsible for building internal Keys. A composer is caller by the builder to build the internal keys based on the Composer logic.

func NewKeyBuilder

func NewKeyBuilder(composer KeyComposer) *KeyBuilder

NewKeyBuilder returns a KeyBuilder.

func (*KeyBuilder) Build

func (k *KeyBuilder) Build(filters []Filter, userDefinedKeys []*schema.Field) ([]keys.Key, error)

Build is responsible for building the internal keys from the user filter and using the keys defined in the schema and passed by the caller in this method. The build is doing a level by level traversal to build the internal Keys. On each level multiple keys can be formed because the user can specify ranges. The builder is not deciding the logic of key generation, the builder is simply traversing on the filters and calling compose where the logic resides.

type KeyComposer

type KeyComposer interface {
	Compose(level []*Selector, userDefinedKeys []*schema.Field, parent LogicalOP) ([]keys.Key, error)
}

KeyComposer needs to be implemented to have a custom Compose method with different constraints.

type LessThanEqMatcher

type LessThanEqMatcher struct {
	Value value.Value
}

LessThanEqMatcher implements "$lte" operand.

func (*LessThanEqMatcher) GetValue

func (l *LessThanEqMatcher) GetValue() value.Value

func (*LessThanEqMatcher) Matches

func (l *LessThanEqMatcher) Matches(input value.Value) bool

func (*LessThanEqMatcher) String

func (l *LessThanEqMatcher) String() string

func (*LessThanEqMatcher) Type

func (l *LessThanEqMatcher) Type() string

type LessThanMatcher

type LessThanMatcher struct {
	Value value.Value
}

LessThanMatcher implements "$lt" operand.

func (*LessThanMatcher) GetValue

func (l *LessThanMatcher) GetValue() value.Value

func (*LessThanMatcher) Matches

func (l *LessThanMatcher) Matches(input value.Value) bool

func (*LessThanMatcher) String

func (l *LessThanMatcher) String() string

func (*LessThanMatcher) Type

func (l *LessThanMatcher) Type() string

type LogicalFilter

type LogicalFilter interface {
	GetFilters() []Filter
	Type() LogicalOP
}

LogicalFilter (or boolean) are the filters that evaluates to True or False. A logical operator can have the following form inside the JSON

{"$and": [{"f1":1}, {"f2": 3}]}
{"$or": [{"f1":1}, {"f2": 3}]}

type LogicalOP

type LogicalOP string
const (
	AndOP LogicalOP = "$and"
	OrOP  LogicalOP = "$or"
)

type OrFilter

type OrFilter struct {
	// contains filtered or unexported fields
}

OrFilter performs a logical OR operation on an array of two or more expressions. The or filter looks like this, {"$or": [{"f1":1}, {"f2": 3}....]} It can be nested i.e. a top level "$or" can have multiple nested $and/$or.

func NewOrFilter

func NewOrFilter(filter []Filter) (*OrFilter, error)

func (*OrFilter) GetFilters

func (o *OrFilter) GetFilters() []Filter

GetFilters returns all the nested filters for OrFilter.

func (*OrFilter) IsIndexed

func (o *OrFilter) IsIndexed() bool

func (*OrFilter) Matches

func (o *OrFilter) Matches(doc []byte) bool

Matches returns true if the input doc matches this filter.

func (*OrFilter) MatchesDoc

func (o *OrFilter) MatchesDoc(doc map[string]interface{}) bool

func (*OrFilter) String

func (o *OrFilter) String() string

String a helpful method for logging.

func (*OrFilter) ToSearchFilter

func (o *OrFilter) ToSearchFilter() []string

func (*OrFilter) Type

func (o *OrFilter) Type() LogicalOP

type Selector

type Selector struct {
	Field     *schema.QueryableField
	Matcher   ValueMatcher
	Collation *value.Collation
}

Selector is a condition defined inside a filter. It has a field which corresponding the field on which condition is defined and then Matcher. A matcher is formed from the user condition i.e. if the condition is on "$eq" then a EqualityMatcher is created. The matcher implements a Match method which is used to know if the input document passes the condition.

A Selector can have this form inside the input JSON

{f:{$eq:1}}
{f:20} (default is "$eq" so we automatically append EqualityMatcher for this case in parser)
{f:<Expr>}

func NewSelector

func NewSelector(field *schema.QueryableField, matcher ValueMatcher, collation *value.Collation) *Selector

NewSelector returns Selector object.

func (*Selector) IsIndexed

func (s *Selector) IsIndexed() bool

func (*Selector) Matches

func (s *Selector) Matches(doc []byte) bool

Matches returns true if the input doc matches this filter.

func (*Selector) MatchesDoc

func (s *Selector) MatchesDoc(doc map[string]interface{}) bool

func (*Selector) String

func (s *Selector) String() string

String a helpful method for logging.

func (*Selector) ToSearchFilter

func (s *Selector) ToSearchFilter() []string

type StrictEqKeyComposer

type StrictEqKeyComposer struct {
	// contains filtered or unexported fields
}

StrictEqKeyComposer is to generate internal keys only if the condition is equality on the fields that are part of the schema and all these fields are present in the filters. The following rules are applied for StrictEqKeyComposer

  • The userDefinedKeys(indexes defined in the schema) passed in parameter should be present in the filter
  • For AND filters it is possible to build internal keys for composite indexes, for OR it is not possible.

So for OR filter an error is returned if it is used for indexes that are composite.

func NewStrictEqKeyComposer

func NewStrictEqKeyComposer(keyEncodingFunc func(indexParts ...interface{}) (keys.Key, error)) *StrictEqKeyComposer

func (*StrictEqKeyComposer) Compose

func (s *StrictEqKeyComposer) Compose(selectors []*Selector, userDefinedKeys []*schema.Field, parent LogicalOP) ([]keys.Key, error)

Compose is implementing the logic of composing keys.

type ValueMatcher

type ValueMatcher interface {
	// Matches returns true if the receiver has the value object that has the same value as input
	Matches(input value.Value) bool

	// Type return the type of the value matcher, syntactic sugar for logging, etc
	Type() string

	// GetValue returns the value on which the Matcher is operating
	GetValue() value.Value
}

ValueMatcher is an interface that has method like Matches.

func NewMatcher

func NewMatcher(key string, v value.Value) (ValueMatcher, error)

NewMatcher returns ValueMatcher that is derived from the key.

type WrappedFilter

type WrappedFilter struct {
	Filter
	// contains filtered or unexported fields
}

func NewWrappedFilter

func NewWrappedFilter(filters []Filter) *WrappedFilter

func (*WrappedFilter) IsIndexed

func (w *WrappedFilter) IsIndexed() bool

func (*WrappedFilter) None

func (w *WrappedFilter) None() bool

func (*WrappedFilter) SearchFilter

func (w *WrappedFilter) SearchFilter() []string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL