You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
8.6 KiB

  1. // Copyright (c) 2014 Couchbase, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package bleve
  15. import (
  16. "github.com/blevesearch/bleve/document"
  17. "github.com/blevesearch/bleve/index"
  18. "github.com/blevesearch/bleve/index/store"
  19. "github.com/blevesearch/bleve/mapping"
  20. "golang.org/x/net/context"
  21. )
  22. // A Batch groups together multiple Index and Delete
  23. // operations you would like performed at the same
  24. // time. The Batch structure is NOT thread-safe.
  25. // You should only perform operations on a batch
  26. // from a single thread at a time. Once batch
  27. // execution has started, you may not modify it.
  28. type Batch struct {
  29. index Index
  30. internal *index.Batch
  31. }
  32. // Index adds the specified index operation to the
  33. // batch. NOTE: the bleve Index is not updated
  34. // until the batch is executed.
  35. func (b *Batch) Index(id string, data interface{}) error {
  36. if id == "" {
  37. return ErrorEmptyID
  38. }
  39. doc := document.NewDocument(id)
  40. err := b.index.Mapping().MapDocument(doc, data)
  41. if err != nil {
  42. return err
  43. }
  44. b.internal.Update(doc)
  45. return nil
  46. }
  47. // Delete adds the specified delete operation to the
  48. // batch. NOTE: the bleve Index is not updated until
  49. // the batch is executed.
  50. func (b *Batch) Delete(id string) {
  51. if id != "" {
  52. b.internal.Delete(id)
  53. }
  54. }
  55. // SetInternal adds the specified set internal
  56. // operation to the batch. NOTE: the bleve Index is
  57. // not updated until the batch is executed.
  58. func (b *Batch) SetInternal(key, val []byte) {
  59. b.internal.SetInternal(key, val)
  60. }
  61. // SetInternal adds the specified delete internal
  62. // operation to the batch. NOTE: the bleve Index is
  63. // not updated until the batch is executed.
  64. func (b *Batch) DeleteInternal(key []byte) {
  65. b.internal.DeleteInternal(key)
  66. }
  67. // Size returns the total number of operations inside the batch
  68. // including normal index operations and internal operations.
  69. func (b *Batch) Size() int {
  70. return len(b.internal.IndexOps) + len(b.internal.InternalOps)
  71. }
  72. // String prints a user friendly string representation of what
  73. // is inside this batch.
  74. func (b *Batch) String() string {
  75. return b.internal.String()
  76. }
  77. // Reset returns a Batch to the empty state so that it can
  78. // be re-used in the future.
  79. func (b *Batch) Reset() {
  80. b.internal.Reset()
  81. }
  82. // An Index implements all the indexing and searching
  83. // capabilities of bleve. An Index can be created
  84. // using the New() and Open() methods.
  85. //
  86. // Index() takes an input value, deduces a DocumentMapping for its type,
  87. // assigns string paths to its fields or values then applies field mappings on
  88. // them.
  89. //
  90. // The DocumentMapping used to index a value is deduced by the following rules:
  91. // 1) If value implements Classifier interface, resolve the mapping from Type().
  92. // 2) If value has a string field or value at IndexMapping.TypeField.
  93. // (defaulting to "_type"), use it to resolve the mapping. Fields addressing
  94. // is described below.
  95. // 3) If IndexMapping.DefaultType is registered, return it.
  96. // 4) Return IndexMapping.DefaultMapping.
  97. //
  98. // Each field or nested field of the value is identified by a string path, then
  99. // mapped to one or several FieldMappings which extract the result for analysis.
  100. //
  101. // Struct values fields are identified by their "json:" tag, or by their name.
  102. // Nested fields are identified by prefixing with their parent identifier,
  103. // separated by a dot.
  104. //
  105. // Map values entries are identified by their string key. Entries not indexed
  106. // by strings are ignored. Entry values are identified recursively like struct
  107. // fields.
  108. //
  109. // Slice and array values are identified by their field name. Their elements
  110. // are processed sequentially with the same FieldMapping.
  111. //
  112. // String, float64 and time.Time values are identified by their field name.
  113. // Other types are ignored.
  114. //
  115. // Each value identifier is decomposed in its parts and recursively address
  116. // SubDocumentMappings in the tree starting at the root DocumentMapping. If a
  117. // mapping is found, all its FieldMappings are applied to the value. If no
  118. // mapping is found and the root DocumentMapping is dynamic, default mappings
  119. // are used based on value type and IndexMapping default configurations.
  120. //
  121. // Finally, mapped values are analyzed, indexed or stored. See
  122. // FieldMapping.Analyzer to know how an analyzer is resolved for a given field.
  123. //
  124. // Examples:
  125. //
  126. // type Date struct {
  127. // Day string `json:"day"`
  128. // Month string
  129. // Year string
  130. // }
  131. //
  132. // type Person struct {
  133. // FirstName string `json:"first_name"`
  134. // LastName string
  135. // BirthDate Date `json:"birth_date"`
  136. // }
  137. //
  138. // A Person value FirstName is mapped by the SubDocumentMapping at
  139. // "first_name". Its LastName is mapped by the one at "LastName". The day of
  140. // BirthDate is mapped to the SubDocumentMapping "day" of the root
  141. // SubDocumentMapping "birth_date". It will appear as the "birth_date.day"
  142. // field in the index. The month is mapped to "birth_date.Month".
  143. type Index interface {
  144. // Index analyzes, indexes or stores mapped data fields. Supplied
  145. // identifier is bound to analyzed data and will be retrieved by search
  146. // requests. See Index interface documentation for details about mapping
  147. // rules.
  148. Index(id string, data interface{}) error
  149. Delete(id string) error
  150. NewBatch() *Batch
  151. Batch(b *Batch) error
  152. // Document returns specified document or nil if the document is not
  153. // indexed or stored.
  154. Document(id string) (*document.Document, error)
  155. // DocCount returns the number of documents in the index.
  156. DocCount() (uint64, error)
  157. Search(req *SearchRequest) (*SearchResult, error)
  158. SearchInContext(ctx context.Context, req *SearchRequest) (*SearchResult, error)
  159. Fields() ([]string, error)
  160. FieldDict(field string) (index.FieldDict, error)
  161. FieldDictRange(field string, startTerm []byte, endTerm []byte) (index.FieldDict, error)
  162. FieldDictPrefix(field string, termPrefix []byte) (index.FieldDict, error)
  163. Close() error
  164. Mapping() mapping.IndexMapping
  165. Stats() *IndexStat
  166. StatsMap() map[string]interface{}
  167. GetInternal(key []byte) ([]byte, error)
  168. SetInternal(key, val []byte) error
  169. DeleteInternal(key []byte) error
  170. // Name returns the name of the index (by default this is the path)
  171. Name() string
  172. // SetName lets you assign your own logical name to this index
  173. SetName(string)
  174. // Advanced returns the indexer and data store, exposing lower level
  175. // methods to enumerate records and access data.
  176. Advanced() (index.Index, store.KVStore, error)
  177. }
  178. // New index at the specified path, must not exist.
  179. // The provided mapping will be used for all
  180. // Index/Search operations.
  181. func New(path string, mapping mapping.IndexMapping) (Index, error) {
  182. return newIndexUsing(path, mapping, Config.DefaultIndexType, Config.DefaultKVStore, nil)
  183. }
  184. // NewMemOnly creates a memory-only index.
  185. // The contents of the index is NOT persisted,
  186. // and will be lost once closed.
  187. // The provided mapping will be used for all
  188. // Index/Search operations.
  189. func NewMemOnly(mapping mapping.IndexMapping) (Index, error) {
  190. return newIndexUsing("", mapping, Config.DefaultIndexType, Config.DefaultMemKVStore, nil)
  191. }
  192. // NewUsing creates index at the specified path,
  193. // which must not already exist.
  194. // The provided mapping will be used for all
  195. // Index/Search operations.
  196. // The specified index type will be used.
  197. // The specified kvstore implementation will be used
  198. // and the provided kvconfig will be passed to its
  199. // constructor. Note that currently the values of kvconfig must
  200. // be able to be marshaled and unmarshaled using the encoding/json library (used
  201. // when reading/writing the index metadata file).
  202. func NewUsing(path string, mapping mapping.IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (Index, error) {
  203. return newIndexUsing(path, mapping, indexType, kvstore, kvconfig)
  204. }
  205. // Open index at the specified path, must exist.
  206. // The mapping used when it was created will be used for all Index/Search operations.
  207. func Open(path string) (Index, error) {
  208. return openIndexUsing(path, nil)
  209. }
  210. // OpenUsing opens index at the specified path, must exist.
  211. // The mapping used when it was created will be used for all Index/Search operations.
  212. // The provided runtimeConfig can override settings
  213. // persisted when the kvstore was created.
  214. func OpenUsing(path string, runtimeConfig map[string]interface{}) (Index, error) {
  215. return openIndexUsing(path, runtimeConfig)
  216. }