2014-07-30 18:30:38 +02:00
|
|
|
// Copyright (c) 2014 Couchbase, Inc.
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
// except in compliance with the License. You may obtain a copy of the License at
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
// Unless required by applicable law or agreed to in writing, software distributed under the
|
|
|
|
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
|
|
// either express or implied. See the License for the specific language governing permissions
|
|
|
|
// and limitations under the License.
|
2014-08-29 20:18:36 +02:00
|
|
|
|
2014-07-30 18:30:38 +02:00
|
|
|
package bleve
|
|
|
|
|
|
|
|
import (
|
2014-08-28 21:38:57 +02:00
|
|
|
"github.com/blevesearch/bleve/document"
|
2014-12-27 22:23:46 +01:00
|
|
|
"github.com/blevesearch/bleve/index"
|
|
|
|
"github.com/blevesearch/bleve/index/store"
|
2014-07-30 18:30:38 +02:00
|
|
|
)
|
|
|
|
|
2014-08-31 16:55:22 +02:00
|
|
|
// A Batch groups together multiple Index and Delete
|
|
|
|
// operations you would like performed at the same
|
2015-05-15 21:04:52 +02:00
|
|
|
// time. The Batch structure is NOT thread-safe.
|
|
|
|
// You should only perform operations on a batch
|
|
|
|
// from a single thread at a time. Once batch
|
|
|
|
// execution has started, you may not modify it.
|
2014-10-31 14:40:23 +01:00
|
|
|
type Batch struct {
|
2015-03-03 19:18:20 +01:00
|
|
|
index Index
|
|
|
|
internal *index.Batch
|
2014-08-11 22:27:18 +02:00
|
|
|
}
|
|
|
|
|
2014-08-31 16:55:22 +02:00
|
|
|
// Index adds the specified index operation to the
|
|
|
|
// batch. NOTE: the bleve Index is not updated
|
|
|
|
// until the batch is executed.
|
2015-04-08 16:41:42 +02:00
|
|
|
func (b *Batch) Index(id string, data interface{}) error {
|
2015-09-28 23:00:08 +02:00
|
|
|
if id == "" {
|
|
|
|
return ErrorEmptyID
|
|
|
|
}
|
2015-03-03 19:18:20 +01:00
|
|
|
doc := document.NewDocument(id)
|
|
|
|
err := b.index.Mapping().mapDocument(doc, data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
b.internal.Update(doc)
|
|
|
|
return nil
|
2014-08-11 22:27:18 +02:00
|
|
|
}
|
|
|
|
|
2014-08-31 16:55:22 +02:00
|
|
|
// Delete adds the specified delete operation to the
|
|
|
|
// batch. NOTE: the bleve Index is not updated until
|
|
|
|
// the batch is executed.
|
2015-04-08 16:41:42 +02:00
|
|
|
func (b *Batch) Delete(id string) {
|
2015-09-28 23:00:08 +02:00
|
|
|
if id != "" {
|
|
|
|
b.internal.Delete(id)
|
|
|
|
}
|
2014-10-31 14:40:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetInternal adds the specified set internal
|
|
|
|
// operation to the batch. NOTE: the bleve Index is
|
|
|
|
// not updated until the batch is executed.
|
2015-04-08 16:41:42 +02:00
|
|
|
func (b *Batch) SetInternal(key, val []byte) {
|
2015-03-03 19:18:20 +01:00
|
|
|
b.internal.SetInternal(key, val)
|
2014-10-31 14:40:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetInternal adds the specified delete internal
|
|
|
|
// operation to the batch. NOTE: the bleve Index is
|
|
|
|
// not updated until the batch is executed.
|
2015-04-08 16:41:42 +02:00
|
|
|
func (b *Batch) DeleteInternal(key []byte) {
|
2015-03-03 19:18:20 +01:00
|
|
|
b.internal.DeleteInternal(key)
|
2014-11-25 17:11:28 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 16:41:42 +02:00
|
|
|
// Size returns the total number of operations inside the batch
|
|
|
|
// including normal index operations and internal operations.
|
|
|
|
func (b *Batch) Size() int {
|
2015-03-03 19:18:20 +01:00
|
|
|
return len(b.internal.IndexOps) + len(b.internal.InternalOps)
|
2014-07-30 18:30:38 +02:00
|
|
|
}
|
|
|
|
|
2016-01-14 23:46:27 +01:00
|
|
|
// String prints a user friendly string representation of what
|
2015-04-08 16:41:42 +02:00
|
|
|
// is inside this batch.
|
|
|
|
func (b *Batch) String() string {
|
|
|
|
return b.internal.String()
|
|
|
|
}
|
|
|
|
|
2015-05-15 21:04:52 +02:00
|
|
|
// Reset returns a Batch to the empty state so that it can
|
|
|
|
// be re-used in the future.
|
|
|
|
func (b *Batch) Reset() {
|
|
|
|
b.internal.Reset()
|
|
|
|
}
|
|
|
|
|
2014-08-31 16:55:22 +02:00
|
|
|
// An Index implements all the indexing and searching
|
|
|
|
// capabilities of bleve. An Index can be created
|
|
|
|
// using the New() and Open() methods.
|
2015-09-23 19:57:38 +02:00
|
|
|
//
|
|
|
|
// Index() takes an input value, deduces a DocumentMapping for its type,
|
|
|
|
// assigns string paths to its fields or values then applies field mappings on
|
|
|
|
// them.
|
|
|
|
//
|
|
|
|
// If the value is a []byte, the indexer attempts to convert it to something
|
|
|
|
// else using the ByteArrayConverter registered as
|
|
|
|
// IndexMapping.ByteArrayConverter. By default, it interprets the value as a
|
|
|
|
// JSON payload and unmarshals it to map[string]interface{}.
|
|
|
|
//
|
|
|
|
// The DocumentMapping used to index a value is deduced by the following rules:
|
|
|
|
// 1) If value implements Classifier interface, resolve the mapping from Type().
|
|
|
|
// 2) If value has a string field or value at IndexMapping.TypeField.
|
|
|
|
// (defaulting to "_type"), use it to resolve the mapping. Fields addressing
|
|
|
|
// is described below.
|
|
|
|
// 3) If IndexMapping.DefaultType is registered, return it.
|
|
|
|
// 4) Return IndexMapping.DefaultMapping.
|
|
|
|
//
|
|
|
|
// Each field or nested field of the value is identified by a string path, then
|
|
|
|
// mapped to one or several FieldMappings which extract the result for analysis.
|
|
|
|
//
|
|
|
|
// Struct values fields are identified by their "json:" tag, or by their name.
|
|
|
|
// Nested fields are identified by prefixing with their parent identifier,
|
|
|
|
// separated by a dot.
|
|
|
|
//
|
|
|
|
// Map values entries are identified by their string key. Entries not indexed
|
|
|
|
// by strings are ignored. Entry values are identified recursively like struct
|
|
|
|
// fields.
|
|
|
|
//
|
|
|
|
// Slice and array values are identified by their field name. Their elements
|
|
|
|
// are processed sequentially with the same FieldMapping.
|
|
|
|
//
|
|
|
|
// String, float64 and time.Time values are identified by their field name.
|
|
|
|
// Other types are ignored.
|
|
|
|
//
|
|
|
|
// Each value identifier is decomposed in its parts and recursively address
|
|
|
|
// SubDocumentMappings in the tree starting at the root DocumentMapping. If a
|
|
|
|
// mapping is found, all its FieldMappings are applied to the value. If no
|
|
|
|
// mapping is found and the root DocumentMapping is dynamic, default mappings
|
|
|
|
// are used based on value type and IndexMapping default configurations.
|
|
|
|
//
|
2015-10-02 17:00:45 +02:00
|
|
|
// Finally, mapped values are analyzed, indexed or stored. See
|
|
|
|
// FieldMapping.Analyzer to know how an analyzer is resolved for a given field.
|
|
|
|
//
|
|
|
|
// Examples:
|
2015-09-23 19:57:38 +02:00
|
|
|
//
|
|
|
|
// type Date struct {
|
|
|
|
// Day string `json:"day"`
|
|
|
|
// Month string
|
|
|
|
// Year string
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// type Person struct {
|
|
|
|
// FirstName string `json:"first_name"`
|
|
|
|
// LastName string
|
|
|
|
// BirthDate Date `json:"birth_date"`
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// A Person value FirstName is mapped by the SubDocumentMapping at
|
|
|
|
// "first_name". Its LastName is mapped by the one at "LastName". The day of
|
|
|
|
// BirthDate is mapped to the SubDocumentMapping "day" of the root
|
|
|
|
// SubDocumentMapping "birth_date". It will appear as the "birth_date.day"
|
|
|
|
// field in the index. The month is mapped to "birth_date.Month".
|
2014-07-30 18:30:38 +02:00
|
|
|
type Index interface {
|
2015-09-23 19:57:38 +02:00
|
|
|
// Index analyzes, indexes or stores mapped data fields. Supplied
|
|
|
|
// identifier is bound to analyzed data and will be retrieved by search
|
|
|
|
// requests. See Index interface documentation for details about mapping
|
|
|
|
// rules.
|
2014-08-11 18:47:29 +02:00
|
|
|
Index(id string, data interface{}) error
|
|
|
|
Delete(id string) error
|
2014-07-30 18:30:38 +02:00
|
|
|
|
2015-03-03 19:18:20 +01:00
|
|
|
NewBatch() *Batch
|
2014-10-31 14:40:23 +01:00
|
|
|
Batch(b *Batch) error
|
2014-08-11 22:27:18 +02:00
|
|
|
|
2015-10-17 18:40:26 +02:00
|
|
|
// Document returns specified document or nil if the document is not
|
|
|
|
// indexed or stored.
|
2014-07-30 18:30:38 +02:00
|
|
|
Document(id string) (*document.Document, error)
|
2015-10-18 10:56:20 +02:00
|
|
|
// DocCount returns the number of documents in the index.
|
2014-10-31 14:40:23 +01:00
|
|
|
DocCount() (uint64, error)
|
2014-07-30 18:30:38 +02:00
|
|
|
|
|
|
|
Search(req *SearchRequest) (*SearchResult, error)
|
|
|
|
|
2014-07-31 17:47:36 +02:00
|
|
|
Fields() ([]string, error)
|
|
|
|
|
2015-03-10 21:22:19 +01:00
|
|
|
FieldDict(field string) (index.FieldDict, error)
|
|
|
|
FieldDictRange(field string, startTerm []byte, endTerm []byte) (index.FieldDict, error)
|
|
|
|
FieldDictPrefix(field string, termPrefix []byte) (index.FieldDict, error)
|
|
|
|
|
2015-11-03 18:11:02 +01:00
|
|
|
// DumpAll returns a channel receiving all index rows as
|
|
|
|
// UpsideDownCouchRow, in lexicographic byte order. If the enumeration
|
|
|
|
// fails, an error is sent. The channel is closed once the enumeration
|
2015-11-13 17:01:18 +01:00
|
|
|
// completes or an error is encountered. The caller must consume all
|
|
|
|
// channel entries until the channel is closed to ensure the transaction
|
|
|
|
// and other resources associated with the enumeration are released.
|
2015-11-03 18:11:02 +01:00
|
|
|
//
|
|
|
|
// DumpAll exists for debugging and tooling purpose and may change in the
|
|
|
|
// future.
|
2014-08-15 19:12:55 +02:00
|
|
|
DumpAll() chan interface{}
|
2015-11-03 18:11:02 +01:00
|
|
|
|
|
|
|
// DumpDoc works like DumpAll but returns only StoredRows and
|
|
|
|
// TermFrequencyRows related to a document.
|
2014-08-15 19:12:55 +02:00
|
|
|
DumpDoc(id string) chan interface{}
|
2015-11-03 18:11:02 +01:00
|
|
|
|
|
|
|
// DumpFields works like DumpAll but returns only FieldRows.
|
2014-08-15 19:12:55 +02:00
|
|
|
DumpFields() chan interface{}
|
2014-07-30 18:30:38 +02:00
|
|
|
|
2014-10-31 14:40:23 +01:00
|
|
|
Close() error
|
2014-08-25 15:06:53 +02:00
|
|
|
|
|
|
|
Mapping() *IndexMapping
|
2014-10-02 20:12:22 +02:00
|
|
|
|
|
|
|
Stats() *IndexStat
|
2014-10-22 22:03:55 +02:00
|
|
|
|
|
|
|
GetInternal(key []byte) ([]byte, error)
|
|
|
|
SetInternal(key, val []byte) error
|
|
|
|
DeleteInternal(key []byte) error
|
2014-12-27 22:23:46 +01:00
|
|
|
|
2016-01-14 23:46:27 +01:00
|
|
|
// Name returns the name of the index (by default this is the path)
|
2015-12-06 20:01:03 +01:00
|
|
|
Name() string
|
|
|
|
// SetName lets you assign your own logical name to this index
|
|
|
|
SetName(string)
|
|
|
|
|
2015-10-17 18:40:26 +02:00
|
|
|
// Advanced returns the indexer and data store, exposing lower level
|
|
|
|
// methods to enumerate records and access data.
|
2014-12-27 22:23:46 +01:00
|
|
|
Advanced() (index.Index, store.KVStore, error)
|
2014-07-30 18:30:38 +02:00
|
|
|
}
|
|
|
|
|
2014-08-31 16:55:22 +02:00
|
|
|
// A Classifier is an interface describing any object
|
|
|
|
// which knows how to identify its own type.
|
2014-08-11 22:27:18 +02:00
|
|
|
type Classifier interface {
|
|
|
|
Type() string
|
|
|
|
}
|
|
|
|
|
2014-08-20 22:58:20 +02:00
|
|
|
// New index at the specified path, must not exist.
|
2014-08-31 16:55:22 +02:00
|
|
|
// The provided mapping will be used for all
|
|
|
|
// Index/Search operations.
|
2014-08-20 22:58:20 +02:00
|
|
|
func New(path string, mapping *IndexMapping) (Index, error) {
|
2015-09-02 19:12:08 +02:00
|
|
|
return newIndexUsing(path, mapping, Config.DefaultIndexType, Config.DefaultKVStore, nil)
|
2014-07-30 18:30:38 +02:00
|
|
|
}
|
2014-08-20 22:58:20 +02:00
|
|
|
|
2014-12-27 22:23:46 +01:00
|
|
|
// NewUsing creates index at the specified path,
|
|
|
|
// which must not already exist.
|
|
|
|
// The provided mapping will be used for all
|
|
|
|
// Index/Search operations.
|
2015-09-02 19:12:08 +02:00
|
|
|
// The specified index type will be used
|
2016-01-14 23:46:27 +01:00
|
|
|
// The specified kvstore implementation will be used
|
2014-12-27 22:23:46 +01:00
|
|
|
// and the provided kvconfig will be passed to its
|
|
|
|
// constructor.
|
2015-09-02 19:12:08 +02:00
|
|
|
func NewUsing(path string, mapping *IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (Index, error) {
|
|
|
|
return newIndexUsing(path, mapping, indexType, kvstore, kvconfig)
|
2014-12-27 22:23:46 +01:00
|
|
|
}
|
|
|
|
|
2014-08-20 22:58:20 +02:00
|
|
|
// Open index at the specified path, must exist.
|
|
|
|
// The mapping used when it was created will be used for all Index/Search operations.
|
|
|
|
func Open(path string) (Index, error) {
|
2015-01-06 23:19:46 +01:00
|
|
|
return openIndexUsing(path, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// OpenUsing opens index at the specified path, must exist.
|
|
|
|
// The mapping used when it was created will be used for all Index/Search operations.
|
|
|
|
// The provided runtimeConfig can override settings
|
|
|
|
// persisted when the kvstore was created.
|
|
|
|
func OpenUsing(path string, runtimeConfig map[string]interface{}) (Index, error) {
|
|
|
|
return openIndexUsing(path, runtimeConfig)
|
2014-08-20 22:58:20 +02:00
|
|
|
}
|