be_indexer

package module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Mar 4, 2022 License: MIT Imports: 11 Imported by: 0

README

Boolean Expression Index

Boolean expression index

算法描述来源于论文:Boolean expression index 为什么写它:

  • 大佬写的(优秀的代码)并没有开源
  • 网络上能看到的描述和实现模糊不清,完全不能够工程化
  • 在线广告、某些功能模块借助其可以实现非常优雅的代码实现
  • 论文没有提及的多值查询的问题没有直接给出实现提示,但是实际应用中都特别需要支持

这个Golang版本基本上是之前实现的C++版本的clone,C++实现移步 使用限制: 因为存在对信息存在编码和压缩,所以存在一些限制,使用时注意规避

  • 文档ID最大值限制为:2^32
  • 每个文档最多拥有256个Conjunction
  • 每个DNF最大支持组合条件(field)个数:256
  • 支持任何可以通过parse值化的类型,见parser的定义
  • 默认倒排容器是hash, 因抽用了8bit用在存储field id,所以最大值数量限制:数值/字符串各2^56个(约7.205...e16)
usage:
package main

import (
	"fmt"

	"github.com/echoface/be_indexer/parser"

	"github.com/echoface/be_indexer/util"

	"github.com/echoface/be_indexer"
)

func buildTestDoc() []*be_indexer.Document {
	return []*be_indexer.Document{}
}

func main() {
	builder := be_indexer.NewIndexerBuilder()
	// or use a compacted version, it faster about 12% than default
	// builder := be_indexer.NewCompactIndexerBuilder()

	// optional special a holder/container for field
	builder.ConfigField("keyword", be_indexer.FieldOption{
		Parser:    parser.ParserNameCommon,
		Container: be_indexer.HolderNameACMatcher,
	})

	for _, doc := range buildTestDoc() {
		err := builder.AddDocument(doc)
		util.PanicIfErr(err, "document can't be resolved")
	}

	indexer := builder.BuildIndex()

	result, e := indexer.Retrieve(map[be_indexer.BEField]be_indexer.Values{
		"age": be_indexer.NewValues2(5),
	})
	fmt.Println(e, result)

	result, e = indexer.Retrieve(map[be_indexer.BEField]be_indexer.Values{
		"ip": be_indexer.NewStrValues2("localhost"),
	})
	fmt.Println(e, result)

	result, e = indexer.Retrieve(map[be_indexer.BEField]be_indexer.Values{
		"age":  be_indexer.NewIntValues2(1),
		"city": be_indexer.NewStrValues2("sh"),
		"tag":  be_indexer.NewValues2("tag1"),
	}, be_indexer.WithStepDetail(), be_indexer.WithDumpEntries())
	fmt.Println(e, result)
}

roaring bitmap based boolean expression index(roaringidx)

基于bitmap的布尔索引实现,相对于Boolean expression index论文的实现, 是利用bitmap在集合运算方面的优势实现的DNF Match逻辑,目前支持普通的倒排 以及基于AhoCorasick的字符串模式匹配逻辑实现。从benchmark 结果来看, 在大规模多fields的场景下, 性能相对于Boolean expression index的实现性能 相对来说要差一些,但是其可理解性要好一点。 bitmap方面借助roaring bitmap的实现,在大基数稀疏场景下可以节省大量的内存。aho corasick 选型上也选取 了使用double array trie的实现,索引上内存有所压缩。

usage
package main

import (
	"fmt"

	"github.com/echoface/be_indexer"
	"github.com/echoface/be_indexer/parser"
	"github.com/echoface/be_indexer/roaringidx"
	"github.com/echoface/be_indexer/util"
)

func main() {

	builder := roaringidx.NewIndexerBuilder()

	builder.ConfigureField("ad_id", roaringidx.FieldSetting{
		Container: roaringidx.ContainerNameDefault,
		Parser:    parser.ParserNameNumber,
	})
	builder.ConfigureField("package", roaringidx.FieldSetting{
		Container: roaringidx.ContainerNameDefault,
		Parser:    parser.ParserNameStrHash,
	})
	builder.ConfigureField("keywords", roaringidx.FieldSetting{
		Container: roaringidx.ContainerNameAcMatch,
		Parser:    parser.ParserNameCommon,
	})

	doc1 := be_indexer.NewDocument(1)
	doc1.AddConjunction(be_indexer.NewConjunction().
		Include("ad_id", be_indexer.NewIntValues(100, 101, 108)).
		Exclude("package", be_indexer.NewStrValues("com.echoface.not")))
	doc1.AddConjunction(be_indexer.NewConjunction().
		Include("package", be_indexer.NewStrValues("com.echoface.in")))

	doc3 := be_indexer.NewDocument(20)
	doc3.AddConjunctions(be_indexer.NewConjunction())

	doc4 := be_indexer.NewDocument(50)
	doc4.AddConjunction(be_indexer.NewConjunction().
		Exclude("ad_id", be_indexer.NewIntValues(100, 108)).
		Include("package", be_indexer.NewStrValues("com.echoface.be")))

	builder.AddDocuments(doc1, doc3, doc4)

	indexer, err := builder.BuildIndexer()
	util.PanicIfErr(err, "should not err here")

	scanner := roaringidx.NewScanner(indexer)
	conjIDs, err := scanner.Retrieve(map[be_indexer.BEField]be_indexer.Values{
		"ad_id":   []interface{}{100, 102},
		"package": []interface{}{"com.echoface.be", "com.echoface.not"},
	})
	fmt.Println(roaringidx.FormatBitMapResult(conjIDs))
	scanner.Reset()
}

Copyright (C) 2018, by HuanGong gonghuan.dev@gmail.com.

Under the MIT License.

See the LICENSE file for details.

Documentation

Index

Constants

View Source
const (
	HolderNameDefault   = "default"
	HolderNameACMatcher = "ac_matcher"
)
View Source
const (
	NULLENTRY EntryID = 0xFFFFFFFFFFFFFFFF

	MaxBEFieldID uint64 = 0xFF             // 8bit
	MaxBEValueID uint64 = 0xFFFFFFFFFFFFFF // 56bit

)
View Source
const (
	DebugLevel = iota
	InfoLevel
	ErrorLevel
)
View Source
const (
	LinearSearchLengthThreshold = 8
)
View Source
const (
	WildcardFieldName = BEField("_Z_")
)

Variables

View Source
var (
	LogLevel int           = InfoLevel // control defaultLogger log level
	Logger   BEIndexLogger = &DefaultLogger{}
)

Functions

func HasHolderBuilder

func HasHolderBuilder(name string) bool

func LogDebugIf

func LogDebugIf(condition bool, format string, v ...interface{})

func LogErrIf

func LogErrIf(condition bool, format string, v ...interface{})

func LogIfErr

func LogIfErr(err error, format string, v ...interface{})

func LogInfoIf

func LogInfoIf(condition bool, format string, v ...interface{})

func NewInt32Values

func NewInt32Values(o ...int32) (res []interface{})

func NewInt32Values2

func NewInt32Values2(v int32, o ...int32) (res []interface{})

func NewInt64Values

func NewInt64Values(o ...int64) (res []interface{})

func NewInt64Values2

func NewInt64Values2(v int64, o ...int64) (res []interface{})

func NewIntValues

func NewIntValues(o ...int) (res []interface{})

func NewIntValues2

func NewIntValues2(v int, o ...int) (res []interface{})

func NewStrValues

func NewStrValues(ss ...string) (res []interface{})

func NewStrValues2

func NewStrValues2(v string, ss ...string) (res []interface{})

func PutCollector

func PutCollector(c *DocIDCollector)

func RegisterEntriesHolder

func RegisterEntriesHolder(name string, builder HolderBuilder) error

Types

type ACEntriesHolder

type ACEntriesHolder struct {
	ACHolderOption

	KeepBuilder bool
	// contains filtered or unexported fields
}

func NewACEntriesHolder

func NewACEntriesHolder(option ACHolderOption) *ACEntriesHolder

NewACEntriesHolder it will default drop the builder after compile ac-machine, you can register a customized ACEntriesHolder(with builder detail), and the register it

RegisterEntriesHolder(HolderNameACMatcher, func() EntriesHolder {
    holder := NewACEntriesHolder()
    holder.KeepBuilder = true
    return holder
})

NOTE: this just for debugging usage, it will consume memory much more

func (*ACEntriesHolder) AddFieldEID

func (h *ACEntriesHolder) AddFieldEID(field *fieldDesc, values Values, eid EntryID) error

func (*ACEntriesHolder) CompileEntries

func (h *ACEntriesHolder) CompileEntries()

func (*ACEntriesHolder) DumpEntries

func (h *ACEntriesHolder) DumpEntries(buffer *strings.Builder)

func (*ACEntriesHolder) EnableDebug

func (h *ACEntriesHolder) EnableDebug(debug bool)

func (*ACEntriesHolder) GetEntries

func (h *ACEntriesHolder) GetEntries(field *fieldDesc, assigns Values) (CursorGroup, error)

type ACHolderOption

type ACHolderOption struct {
	// QuerySep 查询时,当存在多个值时,使用什么分隔符拼接多个查询字段来组成查询语句, 默认使用whitespace
	// 这是因为在语义上'空'更符合逻辑表达的正确性
	QuerySep string
}

type Assignments

type Assignments map[BEField]Values

func (Assignments) Size

func (ass Assignments) Size() (size int)

type BEField

type BEField string

type BEIndex

type BEIndex interface {

	// Retrieve scan index data and retrieve satisfied document
	Retrieve(queries Assignments, opt ...IndexOpt) (DocIDList, error)

	// RetrieveWithCollector scan index data and retrieve satisfied document
	RetrieveWithCollector(Assignments, ResultCollector, ...IndexOpt) error

	// DumpEntries debug api
	DumpEntries() string

	DumpEntriesSummary() string
	// contains filtered or unexported methods
}

func NewSizeGroupedBEIndex

func NewSizeGroupedBEIndex() BEIndex

type BEIndexLogger

type BEIndexLogger interface {
	Debugf(format string, v ...interface{})
	Infof(format string, v ...interface{})
	Errorf(format string, v ...interface{})
}

type BoolValues

type BoolValues struct {
	Incl  bool   `json:"inc"`   // include: true exclude: false
	Value Values `json:"value"` // values can be parser parse to id
}

BoolValues expression a bool logic like: (in) [15,16,17], (not in) [shanghai,yz]

func (*BoolValues) JSONString

func (v *BoolValues) JSONString() string

func (*BoolValues) String

func (v *BoolValues) String() string

type BooleanExpr

type BooleanExpr struct {
	BoolValues
	Field BEField `json:"field"`
}

BooleanExpr expression a bool logic like: age (in) [15,16,17], city (not in) [shanghai,yz]

func NewBoolExpr

func NewBoolExpr(field BEField, inc bool, v Values) *BooleanExpr

func NewBoolExpr2

func NewBoolExpr2(field BEField, expr BoolValues) *BooleanExpr

type CompactedBEIndex

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

func NewCompactedBEIndex

func NewCompactedBEIndex() *CompactedBEIndex

func (*CompactedBEIndex) DumpEntries

func (bi *CompactedBEIndex) DumpEntries() string

func (*CompactedBEIndex) DumpEntriesSummary

func (bi *CompactedBEIndex) DumpEntriesSummary() string

func (*CompactedBEIndex) Retrieve

func (bi *CompactedBEIndex) Retrieve(
	queries Assignments, opts ...IndexOpt) (result DocIDList, err error)

func (*CompactedBEIndex) RetrieveWithCollector

func (bi *CompactedBEIndex) RetrieveWithCollector(
	queries Assignments, collector ResultCollector, opts ...IndexOpt) (err error)

type ConjID

type ConjID uint64

ConjID max support 56bit len |--[(reserved(16)) | size(8bit) | index(8bit) | docID(32bit)]

func NewConjID

func NewConjID(docID DocID, index, size int) ConjID

NewConjID (reserved(16))| size(8bit) | index(8bit) | docID(32bit)

func (ConjID) DocID

func (id ConjID) DocID() DocID

func (ConjID) Index

func (id ConjID) Index() int

func (ConjID) Size

func (id ConjID) Size() int

type Conjunction

type Conjunction struct {
	Expressions map[BEField]*BoolValues `json:"exprs"` // 同一个Conj内不允许重复的Field
}

func NewConjunction

func NewConjunction() *Conjunction

func (*Conjunction) AddBoolExpr

func (conj *Conjunction) AddBoolExpr(expr *BooleanExpr) *Conjunction

func (*Conjunction) AddBoolExprs

func (conj *Conjunction) AddBoolExprs(exprs ...*BooleanExpr)

AddBoolExprs append boolean expression, don't allow same field added twice in one conjunction

func (*Conjunction) AddExpression

func (conj *Conjunction) AddExpression(expr *BooleanExpr) *Conjunction

func (*Conjunction) AddExpression3

func (conj *Conjunction) AddExpression3(field string, include bool, values Values) *Conjunction

func (*Conjunction) CalcConjSize

func (conj *Conjunction) CalcConjSize() (size int)

func (*Conjunction) Exclude

func (conj *Conjunction) Exclude(field BEField, values Values) *Conjunction

func (*Conjunction) In

func (conj *Conjunction) In(field BEField, values Values) *Conjunction

In any value in values is a **true** expression

func (*Conjunction) Include

func (conj *Conjunction) Include(field BEField, values Values) *Conjunction

func (*Conjunction) JSONString

func (conj *Conjunction) JSONString() string

func (*Conjunction) NotIn

func (conj *Conjunction) NotIn(field BEField, values Values) *Conjunction

NotIn any value in values is a **false** expression

func (*Conjunction) String

func (conj *Conjunction) String() string

type CursorGroup

type CursorGroup []*EntriesCursor

func (CursorGroup) DumpEntries

func (cg CursorGroup) DumpEntries(sb *strings.Builder)

type DefaultEntriesHolder

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

DefaultEntriesHolder EntriesHolder implement base on hash map holder map<key, Entries>

func (*DefaultEntriesHolder) AddFieldEID

func (h *DefaultEntriesHolder) AddFieldEID(field *fieldDesc, values Values, eid EntryID) (err error)

func (*DefaultEntriesHolder) AppendEntryID

func (h *DefaultEntriesHolder) AppendEntryID(key Key, id EntryID)

func (*DefaultEntriesHolder) CompileEntries

func (h *DefaultEntriesHolder) CompileEntries()

func (*DefaultEntriesHolder) DumpEntries

func (h *DefaultEntriesHolder) DumpEntries(buffer *strings.Builder)

func (*DefaultEntriesHolder) EnableDebug

func (h *DefaultEntriesHolder) EnableDebug(debug bool)

func (*DefaultEntriesHolder) GetEntries

func (h *DefaultEntriesHolder) GetEntries(field *fieldDesc, assigns Values) (r CursorGroup, e error)

type DefaultLogger

type DefaultLogger struct {
}

DefaultLogger a console logger use fmt lib

func (*DefaultLogger) Debugf

func (l *DefaultLogger) Debugf(format string, v ...interface{})

func (*DefaultLogger) Errorf

func (l *DefaultLogger) Errorf(format string, v ...interface{})

func (*DefaultLogger) Infof

func (l *DefaultLogger) Infof(format string, v ...interface{})

type DocID

type DocID int64

type DocIDCollector

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

DocIDCollector Default Collector with removing duplicated doc

func NewDocIDCollector

func NewDocIDCollector() *DocIDCollector

func PickCollector

func PickCollector() *DocIDCollector

func (*DocIDCollector) Add

func (c *DocIDCollector) Add(docID DocID, _ ConjID)

func (*DocIDCollector) DocCount

func (c *DocIDCollector) DocCount() int

func (*DocIDCollector) GetDocIDs

func (c *DocIDCollector) GetDocIDs() (ids DocIDList)

func (*DocIDCollector) GetDocIDsInto

func (c *DocIDCollector) GetDocIDsInto(ids *DocIDList)

func (*DocIDCollector) Reset

func (c *DocIDCollector) Reset()

type DocIDList

type DocIDList []DocID

func (DocIDList) Contain

func (s DocIDList) Contain(id DocID) bool

func (DocIDList) Len

func (s DocIDList) Len() int

Len sort API

func (DocIDList) Less

func (s DocIDList) Less(i, j int) bool

func (DocIDList) Sub

func (s DocIDList) Sub(other DocIDList) (r DocIDList)

func (DocIDList) Swap

func (s DocIDList) Swap(i, j int)

type Document

type Document struct {
	ID   DocID          `json:"id"`   // 只支持int32最大值个Doc
	Cons []*Conjunction `json:"cons"` // conjunction之间的关系是或,具体描述可以看论文的表述
}

func NewDocument

func NewDocument(id DocID) *Document

func (*Document) AddConjunction

func (doc *Document) AddConjunction(cons ...*Conjunction)

AddConjunction 一组完整的expression, 必须是完整一个描述文档的DNF Bool表达的条件组合*/

func (*Document) AddConjunctions

func (doc *Document) AddConjunctions(conj *Conjunction, others ...*Conjunction)

func (*Document) JSONString

func (doc *Document) JSONString() string

func (*Document) String

func (doc *Document) String() string

String a more compacted string

type Entries

type Entries []EntryID

Entries a type define for sort option

func (Entries) DocString

func (s Entries) DocString() []string

func (Entries) Len

func (s Entries) Len() int

Len Entries sort API

func (Entries) Less

func (s Entries) Less(i, j int) bool

func (Entries) Swap

func (s Entries) Swap(i, j int)

type EntriesContainer

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

EntriesContainer for default Entries Holder, it can hold different field's entries, but for ACMatcher or other Holder, it may only hold entries for one field

func (*EntriesContainer) DumpString

func (c *EntriesContainer) DumpString(buf *strings.Builder)

type EntriesCursor

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

EntriesCursor represent a posting list for one Assign (age, 15): [1, 2, 5, 19, 22] cursor: ^

func NewEntriesCursor

func NewEntriesCursor(key QKey, entries Entries) *EntriesCursor

func (*EntriesCursor) DumpEntries

func (cur *EntriesCursor) DumpEntries(sb *strings.Builder)

func (*EntriesCursor) GetCurEntryID

func (sc *EntriesCursor) GetCurEntryID() EntryID

func (*EntriesCursor) LinearSkip

func (sc *EntriesCursor) LinearSkip(id EntryID) EntryID

func (*EntriesCursor) LinearSkipTo

func (sc *EntriesCursor) LinearSkipTo(id EntryID) EntryID

func (*EntriesCursor) Skip

func (sc *EntriesCursor) Skip(id EntryID) EntryID

func (*EntriesCursor) SkipTo

func (sc *EntriesCursor) SkipTo(id EntryID) EntryID

type EntriesHolder

type EntriesHolder interface {
	EnableDebug(debug bool)

	DumpEntries(buffer *strings.Builder)

	// CompileEntries finalize entries status for query, build or make sorted
	// according to the paper, entries must be sorted
	CompileEntries()

	GetEntries(field *fieldDesc, assigns Values) (CursorGroup, error)

	// AddFieldEID tokenize values and add it to holder container
	AddFieldEID(field *fieldDesc, values Values, eid EntryID) error
}

func NewDefaultEntriesHolder

func NewDefaultEntriesHolder() EntriesHolder

func NewEntriesHolder

func NewEntriesHolder(name string) EntriesHolder

type EntryID

type EntryID uint64

EntryID [-- ConjID(48bit) --|-- empty(15bit) -- | --incl/excl(1bit) --]

|--[(reserved(16)) | size(8bit) | index(8bit)  | docID(32bit)]

func NewEntryID

func NewEntryID(id ConjID, incl bool) EntryID

NewEntryID |-- ConjID(48bit) --|-- empty(15bit) -- | --incl/excl(1bit) --|

func (EntryID) DocString

func (entry EntryID) DocString() string

func (EntryID) GetConjID

func (entry EntryID) GetConjID() ConjID

func (EntryID) IsExclude

func (entry EntryID) IsExclude() bool

func (EntryID) IsInclude

func (entry EntryID) IsInclude() bool

func (EntryID) IsNULLEntry

func (entry EntryID) IsNULLEntry() bool

type FieldCursor

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

FieldCursor for a boolean expression: {"tag", "in", [1, 2, 3]} tag_2: [ID5] tag_1: [ID1, ID2, ID7]

func NewFieldCursor

func NewFieldCursor(cursors ...*EntriesCursor) *FieldCursor

func (*FieldCursor) AddPostingList

func (sg *FieldCursor) AddPostingList(cursor *EntriesCursor)

func (*FieldCursor) DumpEntries

func (sg *FieldCursor) DumpEntries() string

func (*FieldCursor) GetCurConjID

func (sg *FieldCursor) GetCurConjID() ConjID

func (*FieldCursor) GetCurEntryID

func (sg *FieldCursor) GetCurEntryID() EntryID

func (*FieldCursor) ReachEnd

func (sg *FieldCursor) ReachEnd() bool

func (*FieldCursor) Skip

func (sg *FieldCursor) Skip(id EntryID) (newMin EntryID)

func (*FieldCursor) SkipTo

func (sg *FieldCursor) SkipTo(id EntryID) (newMin EntryID)

type FieldCursors

type FieldCursors []*FieldCursor

func (FieldCursors) Dump

func (s FieldCursors) Dump() string

func (FieldCursors) DumpCurrent

func (s FieldCursors) DumpCurrent() string

func (FieldCursors) Len

func (s FieldCursors) Len() int

Len FieldCursors sort API

func (FieldCursors) Less

func (s FieldCursors) Less(i, j int) bool

func (FieldCursors) Sort

func (s FieldCursors) Sort()

Sort golang's internal sort.Sort method have obvious overhead in performance.(runtime convTSlice) so here use a simple insert sort replace it. bz not much Element, may another quickSort here later

func (FieldCursors) Swap

func (s FieldCursors) Swap(i, j int)

type FieldOption

type FieldOption struct {
	Parser parser.FieldValueParser // will create a default parser if parser is nil

	Container string // specify Entries holder for all tokenized value Entries
}

type HolderBuilder

type HolderBuilder func() EntriesHolder

type IndexOpt

type IndexOpt func(ctx *retrieveContext)

func WithCollector

func WithCollector(fn ResultCollector) IndexOpt

WithCollector specify a user defined collector

func WithDumpEntries

func WithDumpEntries() IndexOpt

func WithStepDetail

func WithStepDetail() IndexOpt

type IndexerBuilder

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

func NewCompactIndexerBuilder

func NewCompactIndexerBuilder() *IndexerBuilder

func NewIndexerBuilder

func NewIndexerBuilder() *IndexerBuilder

func (*IndexerBuilder) AddDocument

func (b *IndexerBuilder) AddDocument(doc *Document) error

func (*IndexerBuilder) BuildIndex

func (b *IndexerBuilder) BuildIndex() BEIndex

func (*IndexerBuilder) ConfigField

func (b *IndexerBuilder) ConfigField(field BEField, settings FieldOption)

type IndexerSettings

type IndexerSettings struct {
	FieldConfig map[BEField]FieldOption
}

type Key

type Key uint64

Key is the term represent field and its value, eg: <age,15> <field-8bit> | <value-56bit>

func NewKey

func NewKey(fieldID uint64, valueID uint64) Key

NewKey API

func (Key) GetFieldID

func (key Key) GetFieldID() uint64

func (Key) GetValueID

func (key Key) GetValueID() uint64

func (Key) String

func (key Key) String() string

type QKey

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

func (*QKey) String

func (key *QKey) String() string

type ResultCollector

type ResultCollector interface {
	Add(id DocID, conj ConjID)

	GetDocIDs() (ids DocIDList)

	GetDocIDsInto(ids *DocIDList)
}

type SizeGroupedBEIndex

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

func (*SizeGroupedBEIndex) DumpEntries

func (bi *SizeGroupedBEIndex) DumpEntries() string

func (*SizeGroupedBEIndex) DumpEntriesSummary

func (bi *SizeGroupedBEIndex) DumpEntriesSummary() string

func (*SizeGroupedBEIndex) Retrieve

func (bi *SizeGroupedBEIndex) Retrieve(
	queries Assignments, opts ...IndexOpt) (result DocIDList, err error)

func (*SizeGroupedBEIndex) RetrieveWithCollector

func (bi *SizeGroupedBEIndex) RetrieveWithCollector(
	queries Assignments, collector ResultCollector, opts ...IndexOpt) (err error)

type Values

type Values []interface{}

func NewValues

func NewValues(o ...interface{}) (res Values)

NewValues panic if invalid value

func NewValues2

func NewValues2(v interface{}, o ...interface{}) (res Values)

Directories

Path Synopsis
example
ac_cedar_test command
grouped_indexer command
json_doc command

Jump to

Keyboard shortcuts

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