Documentation ¶
Index ¶
- Constants
- func None(reqFilter []byte) bool
- func PKBuildIndexPartsFunc(name string, value value.Value) []interface{}
- type AndFilter
- func (a *AndFilter) GetFilters() []Filter
- func (a *AndFilter) IsSearchIndexed() bool
- func (a *AndFilter) Matches(doc []byte) bool
- func (a *AndFilter) MatchesDoc(doc map[string]interface{}) bool
- func (a *AndFilter) String() string
- func (a *AndFilter) ToSearchFilter() string
- func (a *AndFilter) Type() LogicalOP
- type BuildIndexPartsFunc
- type EmptyFilter
- type EqualityMatcher
- type Factory
- func (factory *Factory) Factorize(reqFilter []byte) ([]Filter, error)
- func (factory *Factory) ParseSelector(k []byte, v []byte, dataType jsonparser.ValueType) (Filter, error)
- func (factory *Factory) UnmarshalAnd(input jsoniter.RawMessage) (Filter, error)
- func (factory *Factory) UnmarshalFilter(input jsoniter.RawMessage) (expression.Expr, error)
- func (factory *Factory) UnmarshalOr(input jsoniter.RawMessage) (Filter, error)
- func (factory *Factory) WrappedFilter(reqFilter []byte) (*WrappedFilter, error)
- type Filter
- type GreaterThanEqMatcher
- type GreaterThanMatcher
- type KeyBuilder
- func NewKeyBuilder[F fieldable](composer KeyComposer[F], primaryKey bool) *KeyBuilder[F]
- func NewPrimaryKeyEqBuilder(keyEncodingFunc KeyEncodingFunc) *KeyBuilder[*schema.Field]
- func NewRangeKeyBuilder(composer KeyComposer[*schema.QueryableField], primaryKey bool) *KeyBuilder[*schema.QueryableField]
- func NewSecondaryKeyEqBuilder[F fieldable](keyEncodingFunc KeyEncodingFunc, buildIndexPartsFunc BuildIndexPartsFunc) *KeyBuilder[F]
- type KeyComposer
- type KeyEncodingFunc
- type LessThanEqMatcher
- type LessThanMatcher
- type LogicalFilter
- type LogicalOP
- type OrFilter
- func (o *OrFilter) GetFilters() []Filter
- func (o *OrFilter) IsSearchIndexed() bool
- func (o *OrFilter) Matches(doc []byte) bool
- func (o *OrFilter) MatchesDoc(doc map[string]interface{}) bool
- func (o *OrFilter) String() string
- func (o *OrFilter) ToSearchFilter() string
- func (o *OrFilter) Type() LogicalOP
- type QueryPlan
- type QueryPlanType
- type RangeKeyComposer
- type Selector
- type StrictEqKeyComposer
- type ValueMatcher
- type WrappedFilter
Constants ¶
const ( EQ = "$eq" GT = "$gt" LT = "$lt" GTE = "$gte" LTE = "$lte" )
Variables ¶
This section is empty.
Functions ¶
func PKBuildIndexPartsFunc ¶
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 (*AndFilter) GetFilters ¶
GetFilters returns all the nested filters for AndFilter.
func (*AndFilter) IsSearchIndexed ¶
func (*AndFilter) MatchesDoc ¶
func (*AndFilter) ToSearchFilter ¶
type BuildIndexPartsFunc ¶
type EmptyFilter ¶
type EmptyFilter struct{}
func (*EmptyFilter) IsSearchIndexed ¶
func (f *EmptyFilter) IsSearchIndexed() 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 ¶
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) 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 NewFactoryForSecondaryIndex ¶
func NewFactoryForSecondaryIndex(fields []*schema.QueryableField) *Factory
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 // IsSearchIndexed to let caller knows if there is any fields in the query not indexed in search. This // will trigger full scan. IsSearchIndexed() 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 ¶
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 ¶
GreaterThanMatcher implements "$gt" operand.
func (*GreaterThanMatcher) GetValue ¶
func (g *GreaterThanMatcher) GetValue() value.Value
func (*GreaterThanMatcher) String ¶
func (g *GreaterThanMatcher) String() string
func (*GreaterThanMatcher) Type ¶
func (g *GreaterThanMatcher) Type() string
type KeyBuilder ¶
type KeyBuilder[F fieldable] 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. KeyBuilder uses generics so that it can accept either schema.QueryableField or schema.Field so that it can build a query plan for primay or secondary indexes.
func NewKeyBuilder ¶
func NewKeyBuilder[F fieldable](composer KeyComposer[F], primaryKey bool) *KeyBuilder[F]
NewKeyBuilder returns a KeyBuilder.
func NewPrimaryKeyEqBuilder ¶
func NewPrimaryKeyEqBuilder(keyEncodingFunc KeyEncodingFunc) *KeyBuilder[*schema.Field]
NewPrimaryKeyEQBuild returns a KeyBuilder for use with schema.Field to build a primary key query plan.
func NewRangeKeyBuilder ¶
func NewRangeKeyBuilder(composer KeyComposer[*schema.QueryableField], primaryKey bool) *KeyBuilder[*schema.QueryableField]
NewRangeKeyBuilder returns a KeyBuilder for use with schema.QueryableField.
func NewSecondaryKeyEqBuilder ¶
func NewSecondaryKeyEqBuilder[F fieldable](keyEncodingFunc KeyEncodingFunc, buildIndexPartsFunc BuildIndexPartsFunc) *KeyBuilder[F]
NewSecondaryKeyEQBuild returns a KeyBuilder for use with the secondary index.
func (*KeyBuilder[F]) Build ¶
func (k *KeyBuilder[F]) Build(filters []Filter, userDefinedKeys []F) ([]QueryPlan, 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. If the build is for a primary key, the query plans are merged into a single plan.
type KeyComposer ¶
type KeyComposer[F fieldable] interface {
Compose(level []*Selector, userDefinedKeys []F, parent LogicalOP) ([]QueryPlan, error)
}
KeyComposer needs to be implemented to have a custom Compose method with different constraints.
type KeyEncodingFunc ¶
type LessThanEqMatcher ¶
LessThanEqMatcher implements "$lte" operand.
func (*LessThanEqMatcher) GetValue ¶
func (l *LessThanEqMatcher) GetValue() value.Value
func (*LessThanEqMatcher) String ¶
func (l *LessThanEqMatcher) String() string
func (*LessThanEqMatcher) Type ¶
func (l *LessThanEqMatcher) Type() string
type LessThanMatcher ¶
LessThanMatcher implements "$lt" operand.
func (*LessThanMatcher) GetValue ¶
func (l *LessThanMatcher) GetValue() value.Value
func (*LessThanMatcher) String ¶
func (l *LessThanMatcher) String() string
func (*LessThanMatcher) Type ¶
func (l *LessThanMatcher) Type() string
type LogicalFilter ¶
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 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 (*OrFilter) GetFilters ¶
GetFilters returns all the nested filters for OrFilter.
func (*OrFilter) IsSearchIndexed ¶
func (*OrFilter) MatchesDoc ¶
func (*OrFilter) ToSearchFilter ¶
type QueryPlan ¶
type QueryPlan struct { QueryType QueryPlanType DataType schema.FieldType Keys []keys.Key }
The KeyBuilder returns a QueryPlan that contains the keys and type of query against fdb.
func SortQueryPlans ¶
Sort these by QueryPlanType. This creates a simple way to choose a best query plan based on the queryType.
func (QueryPlan) GetKeyInterfaceParts ¶
func (q QueryPlan) GetKeyInterfaceParts() [][]interface{}
type RangeKeyComposer ¶
type RangeKeyComposer[F fieldable] struct {
// contains filtered or unexported fields
}
Range Key Composer will generate a range key set on the user defined keys It will set the KeyQuery to `FullRange` if the start or end key is not defined in the query if there is a defined start and end key for a range then `Range` is set.
func NewRangeKeyComposer ¶
func NewRangeKeyComposer[F fieldable](keyEncodingFunc KeyEncodingFunc, buildIndexParts BuildIndexPartsFunc) *RangeKeyComposer[F]
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) IsSearchIndexed ¶
func (*Selector) Matches ¶
Matches returns true if the input doc matches this filter. To note around the order of checking for not exist and error logging An error is returned if the field does not exist and that is an acceptable error, so return false Only log an error that is unexpected.
func (*Selector) MatchesDoc ¶
func (*Selector) ToSearchFilter ¶
type StrictEqKeyComposer ¶
type StrictEqKeyComposer[F fieldable] struct {
// contains filtered or unexported fields
}
StrictEqKeyComposer works in to ways to generate internal keys if the condition is equality.
- When `matchAll=true`, it will generate internal keys of equality on the fields of the schema if 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.
2. When `matchAll=false`, it will treat all userDefined as individual and generate an `$eq` query plan for each one that is found.
For OR filter an error is returned if it is used for indexes that are composite.
func NewStrictEqKeyComposer ¶
func NewStrictEqKeyComposer[F fieldable](keyEncodingFunc KeyEncodingFunc, buildIndexPartsFunc BuildIndexPartsFunc, matchAll bool) *StrictEqKeyComposer[F]
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) IsSearchIndexed ¶
func (w *WrappedFilter) IsSearchIndexed() bool
func (*WrappedFilter) None ¶
func (w *WrappedFilter) None() bool
func (*WrappedFilter) SearchFilter ¶
func (w *WrappedFilter) SearchFilter() string