diff --git a/examples_test.go b/examples_test.go index a0e8e097..82ac57fa 100644 --- a/examples_test.go +++ b/examples_test.go @@ -15,11 +15,12 @@ import ( "testing" "time" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/highlight/highlighters/ansi" ) -var mapping *IndexMapping +var indexMapping mapping.IndexMapping var example_index Index var err error @@ -43,8 +44,8 @@ func TestMain(m *testing.M) { } func ExampleNew() { - mapping = NewIndexMapping() - example_index, err = New("path_to_index", mapping) + indexMapping = NewIndexMapping() + example_index, err = New("path_to_index", indexMapping) if err != nil { panic(err) } diff --git a/http/index_get.go b/http/index_get.go index 360e2cd6..7b77900c 100644 --- a/http/index_get.go +++ b/http/index_get.go @@ -13,7 +13,7 @@ import ( "fmt" "net/http" - "github.com/blevesearch/bleve" + "github.com/blevesearch/bleve/mapping" ) type GetIndexHandler struct { @@ -42,9 +42,9 @@ func (h *GetIndexHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } rv := struct { - Status string `json:"status"` - Name string `json:"name"` - Mapping *bleve.IndexMapping `json:"mapping"` + Status string `json:"status"` + Name string `json:"name"` + Mapping mapping.IndexMapping `json:"mapping"` }{ Status: "ok", Name: indexName, diff --git a/index.go b/index.go index df708c62..fafea12e 100644 --- a/index.go +++ b/index.go @@ -13,6 +13,7 @@ import ( "github.com/blevesearch/bleve/document" "github.com/blevesearch/bleve/index" "github.com/blevesearch/bleve/index/store" + "github.com/blevesearch/bleve/mapping" "golang.org/x/net/context" ) @@ -35,7 +36,7 @@ func (b *Batch) Index(id string, data interface{}) error { return ErrorEmptyID } doc := document.NewDocument(id) - err := b.index.Mapping().mapDocument(doc, data) + err := b.index.Mapping().MapDocument(doc, data) if err != nil { return err } @@ -92,11 +93,6 @@ func (b *Batch) Reset() { // 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. @@ -178,7 +174,7 @@ type Index interface { Close() error - Mapping() *IndexMapping + Mapping() mapping.IndexMapping Stats() *IndexStat StatsMap() map[string]interface{} @@ -197,16 +193,10 @@ type Index interface { Advanced() (index.Index, store.KVStore, error) } -// A Classifier is an interface describing any object -// which knows how to identify its own type. -type Classifier interface { - Type() string -} - // New index at the specified path, must not exist. // The provided mapping will be used for all // Index/Search operations. -func New(path string, mapping *IndexMapping) (Index, error) { +func New(path string, mapping mapping.IndexMapping) (Index, error) { return newIndexUsing(path, mapping, Config.DefaultIndexType, Config.DefaultKVStore, nil) } @@ -215,7 +205,7 @@ func New(path string, mapping *IndexMapping) (Index, error) { // and will be lost once closed. // The provided mapping will be used for all // Index/Search operations. -func NewMemOnly(mapping *IndexMapping) (Index, error) { +func NewMemOnly(mapping mapping.IndexMapping) (Index, error) { return newIndexUsing("", mapping, Config.DefaultIndexType, Config.DefaultMemKVStore, nil) } @@ -227,7 +217,7 @@ func NewMemOnly(mapping *IndexMapping) (Index, error) { // The specified kvstore implementation will be used // and the provided kvconfig will be passed to its // constructor. -func NewUsing(path string, mapping *IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (Index, error) { +func NewUsing(path string, mapping mapping.IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (Index, error) { return newIndexUsing(path, mapping, indexType, kvstore, kvconfig) } diff --git a/index_alias_impl.go b/index_alias_impl.go index ea3d6fb5..a379efb0 100644 --- a/index_alias_impl.go +++ b/index_alias_impl.go @@ -19,6 +19,7 @@ import ( "github.com/blevesearch/bleve/document" "github.com/blevesearch/bleve/index" "github.com/blevesearch/bleve/index/store" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" ) @@ -259,7 +260,7 @@ func (i *indexAliasImpl) Close() error { return nil } -func (i *indexAliasImpl) Mapping() *IndexMapping { +func (i *indexAliasImpl) Mapping() mapping.IndexMapping { i.mutex.RLock() defer i.mutex.RUnlock() diff --git a/index_alias_impl_test.go b/index_alias_impl_test.go index b45a312e..92a48fb0 100644 --- a/index_alias_impl_test.go +++ b/index_alias_impl_test.go @@ -11,6 +11,7 @@ import ( "github.com/blevesearch/bleve/document" "github.com/blevesearch/bleve/index" "github.com/blevesearch/bleve/index/store" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/numeric_util" "github.com/blevesearch/bleve/search" ) @@ -1269,7 +1270,7 @@ func (i *stubIndex) Close() error { return i.err } -func (i *stubIndex) Mapping() *IndexMapping { +func (i *stubIndex) Mapping() mapping.IndexMapping { return nil } diff --git a/index_impl.go b/index_impl.go index aae26a0b..1d581cc0 100644 --- a/index_impl.go +++ b/index_impl.go @@ -23,6 +23,7 @@ import ( "github.com/blevesearch/bleve/index" "github.com/blevesearch/bleve/index/store" "github.com/blevesearch/bleve/index/upside_down" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/registry" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/collectors" @@ -35,7 +36,7 @@ type indexImpl struct { name string meta *indexMeta i index.Index - m *IndexMapping + m mapping.IndexMapping mutex sync.RWMutex open bool stats *IndexStat @@ -49,7 +50,7 @@ func indexStorePath(path string) string { return path + string(os.PathSeparator) + storePath } -func newIndexUsing(path string, mapping *IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (*indexImpl, error) { +func newIndexUsing(path string, mapping mapping.IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (*indexImpl, error) { // first validate the mapping err := mapping.Validate() if err != nil { @@ -183,7 +184,7 @@ func openIndexUsing(path string, runtimeConfig map[string]interface{}) (rv *inde return nil, err } - var im IndexMapping + var im *mapping.IndexMappingImpl err = json.Unmarshal(mappingBytes, &im) if err != nil { return nil, fmt.Errorf("error parsing mapping JSON: %v\nmapping contents:\n%s", err, string(mappingBytes)) @@ -202,7 +203,7 @@ func openIndexUsing(path string, runtimeConfig map[string]interface{}) (rv *inde return rv, err } - rv.m = &im + rv.m = im indexStats.Register(rv) return rv, err } @@ -219,7 +220,7 @@ func (i *indexImpl) Advanced() (index.Index, store.KVStore, error) { // Mapping returns the IndexMapping in use by this // Index. -func (i *indexImpl) Mapping() *IndexMapping { +func (i *indexImpl) Mapping() mapping.IndexMapping { return i.m } @@ -239,7 +240,7 @@ func (i *indexImpl) Index(id string, data interface{}) (err error) { } doc := document.NewDocument(id) - err = i.m.mapDocument(doc, data) + err = i.m.MapDocument(doc, data) if err != nil { return } @@ -387,7 +388,7 @@ func (i *indexImpl) SearchInContext(ctx context.Context, req *SearchRequest) (sr } else if facetRequest.DateTimeRanges != nil { // build date range facet facetBuilder := facets.NewDateTimeFacetBuilder(facetRequest.Field, facetRequest.Size) - dateTimeParser := i.m.dateTimeParserNamed(i.m.DefaultDateTimeParser) + dateTimeParser := i.m.DateTimeParserNamed("") for _, dr := range facetRequest.DateTimeRanges { dr.ParseDates(dateTimeParser) facetBuilder.AddRange(dr.Name, dr.Start, dr.End) diff --git a/index_test.go b/index_test.go index 9fdeb175..05341f99 100644 --- a/index_test.go +++ b/index_test.go @@ -29,6 +29,7 @@ import ( "github.com/blevesearch/bleve/analysis/analyzers/keyword_analyzer" "github.com/blevesearch/bleve/index" "github.com/blevesearch/bleve/index/store/null" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" ) @@ -365,7 +366,7 @@ func (s *slowQuery) SetField(f string) Query { return s.actual.SetField(f) } -func (s *slowQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (s *slowQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { time.Sleep(s.delay) return s.actual.Searcher(i, m, explain) } diff --git a/mapping.go b/mapping.go new file mode 100644 index 00000000..e1ce7242 --- /dev/null +++ b/mapping.go @@ -0,0 +1,56 @@ +// 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. + +package bleve + +import "github.com/blevesearch/bleve/mapping" + +// NewIndexMapping creates a new IndexMapping that will use all the default indexing rules +func NewIndexMapping() *mapping.IndexMappingImpl { + return mapping.NewIndexMapping() +} + +// NewDocumentMapping returns a new document mapping +// with all the default values. +func NewDocumentMapping() *mapping.DocumentMapping { + return mapping.NewDocumentMapping() +} + +// NewDocumentStaticMapping returns a new document +// mapping that will not automatically index parts +// of a document without an explicit mapping. +func NewDocumentStaticMapping() *mapping.DocumentMapping { + return mapping.NewDocumentStaticMapping() +} + +// NewDocumentDisabledMapping returns a new document +// mapping that will not perform any indexing. +func NewDocumentDisabledMapping() *mapping.DocumentMapping { + return mapping.NewDocumentDisabledMapping() +} + +// NewTextFieldMapping returns a default field mapping for text +func NewTextFieldMapping() *mapping.FieldMapping { + return mapping.NewTextFieldMapping() +} + +// NewNumericFieldMapping returns a default field mapping for numbers +func NewNumericFieldMapping() *mapping.FieldMapping { + return mapping.NewNumericFieldMapping() +} + +// NewDateTimeFieldMapping returns a default field mapping for dates +func NewDateTimeFieldMapping() *mapping.FieldMapping { + return mapping.NewDateTimeFieldMapping() +} + +// NewBooleanFieldMapping returns a default field mapping for booleans +func NewBooleanFieldMapping() *mapping.FieldMapping { + return mapping.NewBooleanFieldMapping() +} diff --git a/mapping/analysis.go b/mapping/analysis.go new file mode 100644 index 00000000..9ff56553 --- /dev/null +++ b/mapping/analysis.go @@ -0,0 +1,94 @@ +// 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. + +package mapping + +type customAnalysis struct { + CharFilters map[string]map[string]interface{} `json:"char_filters,omitempty"` + Tokenizers map[string]map[string]interface{} `json:"tokenizers,omitempty"` + TokenMaps map[string]map[string]interface{} `json:"token_maps,omitempty"` + TokenFilters map[string]map[string]interface{} `json:"token_filters,omitempty"` + Analyzers map[string]map[string]interface{} `json:"analyzers,omitempty"` + DateTimeParsers map[string]map[string]interface{} `json:"date_time_parsers,omitempty"` +} + +func (c *customAnalysis) registerAll(i *IndexMappingImpl) error { + for name, config := range c.CharFilters { + _, err := i.cache.DefineCharFilter(name, config) + if err != nil { + return err + } + } + + if len(c.Tokenizers) > 0 { + // put all the names in map tracking work to do + todo := map[string]struct{}{} + for name := range c.Tokenizers { + todo[name] = struct{}{} + } + registered := 1 + errs := []error{} + // as long as we keep making progress, keep going + for len(todo) > 0 && registered > 0 { + registered = 0 + errs = []error{} + for name := range todo { + config := c.Tokenizers[name] + _, err := i.cache.DefineTokenizer(name, config) + if err != nil { + errs = append(errs, err) + } else { + delete(todo, name) + registered++ + } + } + } + + if len(errs) > 0 { + return errs[0] + } + } + for name, config := range c.TokenMaps { + _, err := i.cache.DefineTokenMap(name, config) + if err != nil { + return err + } + } + for name, config := range c.TokenFilters { + _, err := i.cache.DefineTokenFilter(name, config) + if err != nil { + return err + } + } + for name, config := range c.Analyzers { + _, err := i.cache.DefineAnalyzer(name, config) + if err != nil { + return err + } + } + for name, config := range c.DateTimeParsers { + _, err := i.cache.DefineDateTimeParser(name, config) + if err != nil { + return err + } + } + return nil +} + +func newCustomAnalysis() *customAnalysis { + rv := customAnalysis{ + CharFilters: make(map[string]map[string]interface{}), + Tokenizers: make(map[string]map[string]interface{}), + TokenMaps: make(map[string]map[string]interface{}), + TokenFilters: make(map[string]map[string]interface{}), + Analyzers: make(map[string]map[string]interface{}), + DateTimeParsers: make(map[string]map[string]interface{}), + } + return &rv +} diff --git a/mapping_document.go b/mapping/document.go similarity index 99% rename from mapping_document.go rename to mapping/document.go index 5bea75aa..19d04210 100644 --- a/mapping_document.go +++ b/mapping/document.go @@ -7,7 +7,7 @@ // either express or implied. See the License for the specific language governing permissions // and limitations under the License. -package bleve +package mapping import ( "encoding/json" @@ -405,7 +405,7 @@ func (dm *DocumentMapping) processProperty(property interface{}, path []string, // automatic indexing behavior // first see if it can be parsed by the default date parser - dateTimeParser := context.im.dateTimeParserNamed(context.im.DefaultDateTimeParser) + dateTimeParser := context.im.DateTimeParserNamed(context.im.DefaultDateTimeParser) if dateTimeParser != nil { parsedDateTime, err := dateTimeParser.ParseDateTime(propertyValueString) if err != nil { diff --git a/mapping_field.go b/mapping/field.go similarity index 95% rename from mapping_field.go rename to mapping/field.go index 1a310b3a..58cac1fc 100644 --- a/mapping_field.go +++ b/mapping/field.go @@ -7,7 +7,7 @@ // either express or implied. See the License for the specific language governing permissions // and limitations under the License. -package bleve +package mapping import ( "encoding/json" @@ -61,7 +61,7 @@ func NewTextFieldMapping() *FieldMapping { } } -func newTextFieldMappingDynamic(im *IndexMapping) *FieldMapping { +func newTextFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { rv := NewTextFieldMapping() rv.Store = im.StoreDynamic rv.Index = im.IndexDynamic @@ -78,7 +78,7 @@ func NewNumericFieldMapping() *FieldMapping { } } -func newNumericFieldMappingDynamic(im *IndexMapping) *FieldMapping { +func newNumericFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { rv := NewNumericFieldMapping() rv.Store = im.StoreDynamic rv.Index = im.IndexDynamic @@ -95,7 +95,7 @@ func NewDateTimeFieldMapping() *FieldMapping { } } -func newDateTimeFieldMappingDynamic(im *IndexMapping) *FieldMapping { +func newDateTimeFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { rv := NewDateTimeFieldMapping() rv.Store = im.StoreDynamic rv.Index = im.IndexDynamic @@ -112,7 +112,7 @@ func NewBooleanFieldMapping() *FieldMapping { } } -func newBooleanFieldMappingDynamic(im *IndexMapping) *FieldMapping { +func newBooleanFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { rv := NewBooleanFieldMapping() rv.Store = im.StoreDynamic rv.Index = im.IndexDynamic @@ -150,7 +150,7 @@ func (fm *FieldMapping) processString(propertyValueString string, pathString str if fm.DateFormat != "" { dateTimeFormat = fm.DateFormat } - dateTimeParser := context.im.dateTimeParserNamed(dateTimeFormat) + dateTimeParser := context.im.DateTimeParserNamed(dateTimeFormat) if dateTimeParser != nil { parsedDateTime, err := dateTimeParser.ParseDateTime(propertyValueString) if err == nil { @@ -211,7 +211,7 @@ func (fm *FieldMapping) analyzerForField(path []string, context *walkContext) *a analyzerName = context.im.DefaultAnalyzer } } - return context.im.analyzerNamed(analyzerName) + return context.im.AnalyzerNamed(analyzerName) } func getFieldName(pathString string, path []string, fieldMapping *FieldMapping) string { diff --git a/mapping_index.go b/mapping/index.go similarity index 73% rename from mapping_index.go rename to mapping/index.go index d91b0751..84e0e479 100644 --- a/mapping_index.go +++ b/mapping/index.go @@ -7,7 +7,7 @@ // either express or implied. See the License for the specific language governing permissions // and limitations under the License. -package bleve +package mapping import ( "encoding/json" @@ -28,98 +28,14 @@ const defaultField = "_all" const defaultAnalyzer = standard_analyzer.Name const defaultDateTimeParser = datetime_optional.Name -type customAnalysis struct { - CharFilters map[string]map[string]interface{} `json:"char_filters,omitempty"` - Tokenizers map[string]map[string]interface{} `json:"tokenizers,omitempty"` - TokenMaps map[string]map[string]interface{} `json:"token_maps,omitempty"` - TokenFilters map[string]map[string]interface{} `json:"token_filters,omitempty"` - Analyzers map[string]map[string]interface{} `json:"analyzers,omitempty"` - DateTimeParsers map[string]map[string]interface{} `json:"date_time_parsers,omitempty"` -} - -func (c *customAnalysis) registerAll(i *IndexMapping) error { - for name, config := range c.CharFilters { - _, err := i.cache.DefineCharFilter(name, config) - if err != nil { - return err - } - } - - if len(c.Tokenizers) > 0 { - // put all the names in map tracking work to do - todo := map[string]struct{}{} - for name := range c.Tokenizers { - todo[name] = struct{}{} - } - registered := 1 - errs := []error{} - // as long as we keep making progress, keep going - for len(todo) > 0 && registered > 0 { - registered = 0 - errs = []error{} - for name := range todo { - config := c.Tokenizers[name] - _, err := i.cache.DefineTokenizer(name, config) - if err != nil { - errs = append(errs, err) - } else { - delete(todo, name) - registered++ - } - } - } - - if len(errs) > 0 { - return errs[0] - } - } - for name, config := range c.TokenMaps { - _, err := i.cache.DefineTokenMap(name, config) - if err != nil { - return err - } - } - for name, config := range c.TokenFilters { - _, err := i.cache.DefineTokenFilter(name, config) - if err != nil { - return err - } - } - for name, config := range c.Analyzers { - _, err := i.cache.DefineAnalyzer(name, config) - if err != nil { - return err - } - } - for name, config := range c.DateTimeParsers { - _, err := i.cache.DefineDateTimeParser(name, config) - if err != nil { - return err - } - } - return nil -} - -func newCustomAnalysis() *customAnalysis { - rv := customAnalysis{ - CharFilters: make(map[string]map[string]interface{}), - Tokenizers: make(map[string]map[string]interface{}), - TokenMaps: make(map[string]map[string]interface{}), - TokenFilters: make(map[string]map[string]interface{}), - Analyzers: make(map[string]map[string]interface{}), - DateTimeParsers: make(map[string]map[string]interface{}), - } - return &rv -} - -// An IndexMapping controls how objects are placed +// An IndexMappingImpl controls how objects are placed // into an index. // First the type of the object is determined. // Once the type is know, the appropriate // DocumentMapping is selected by the type. // If no mapping was determined for that type, // a DefaultMapping will be used. -type IndexMapping struct { +type IndexMappingImpl struct { TypeMapping map[string]*DocumentMapping `json:"types,omitempty"` DefaultMapping *DocumentMapping `json:"default_mapping"` TypeField string `json:"type_field"` @@ -134,7 +50,7 @@ type IndexMapping struct { } // AddCustomCharFilter defines a custom char filter for use in this mapping -func (im *IndexMapping) AddCustomCharFilter(name string, config map[string]interface{}) error { +func (im *IndexMappingImpl) AddCustomCharFilter(name string, config map[string]interface{}) error { _, err := im.cache.DefineCharFilter(name, config) if err != nil { return err @@ -144,7 +60,7 @@ func (im *IndexMapping) AddCustomCharFilter(name string, config map[string]inter } // AddCustomTokenizer defines a custom tokenizer for use in this mapping -func (im *IndexMapping) AddCustomTokenizer(name string, config map[string]interface{}) error { +func (im *IndexMappingImpl) AddCustomTokenizer(name string, config map[string]interface{}) error { _, err := im.cache.DefineTokenizer(name, config) if err != nil { return err @@ -154,7 +70,7 @@ func (im *IndexMapping) AddCustomTokenizer(name string, config map[string]interf } // AddCustomTokenMap defines a custom token map for use in this mapping -func (im *IndexMapping) AddCustomTokenMap(name string, config map[string]interface{}) error { +func (im *IndexMappingImpl) AddCustomTokenMap(name string, config map[string]interface{}) error { _, err := im.cache.DefineTokenMap(name, config) if err != nil { return err @@ -164,7 +80,7 @@ func (im *IndexMapping) AddCustomTokenMap(name string, config map[string]interfa } // AddCustomTokenFilter defines a custom token filter for use in this mapping -func (im *IndexMapping) AddCustomTokenFilter(name string, config map[string]interface{}) error { +func (im *IndexMappingImpl) AddCustomTokenFilter(name string, config map[string]interface{}) error { _, err := im.cache.DefineTokenFilter(name, config) if err != nil { return err @@ -202,7 +118,7 @@ func (im *IndexMapping) AddCustomTokenFilter(name string, config map[string]inte // ... // }, // }) -func (im *IndexMapping) AddCustomAnalyzer(name string, config map[string]interface{}) error { +func (im *IndexMappingImpl) AddCustomAnalyzer(name string, config map[string]interface{}) error { _, err := im.cache.DefineAnalyzer(name, config) if err != nil { return err @@ -212,7 +128,7 @@ func (im *IndexMapping) AddCustomAnalyzer(name string, config map[string]interfa } // AddCustomDateTimeParser defines a custom date time parser for use in this mapping -func (im *IndexMapping) AddCustomDateTimeParser(name string, config map[string]interface{}) error { +func (im *IndexMappingImpl) AddCustomDateTimeParser(name string, config map[string]interface{}) error { _, err := im.cache.DefineDateTimeParser(name, config) if err != nil { return err @@ -222,8 +138,8 @@ func (im *IndexMapping) AddCustomDateTimeParser(name string, config map[string]i } // NewIndexMapping creates a new IndexMapping that will use all the default indexing rules -func NewIndexMapping() *IndexMapping { - return &IndexMapping{ +func NewIndexMapping() *IndexMappingImpl { + return &IndexMappingImpl{ TypeMapping: make(map[string]*DocumentMapping), DefaultMapping: NewDocumentMapping(), TypeField: defaultTypeField, @@ -240,7 +156,7 @@ func NewIndexMapping() *IndexMapping { // Validate will walk the entire structure ensuring the following // explicitly named and default analyzers can be built -func (im *IndexMapping) Validate() error { +func (im *IndexMappingImpl) Validate() error { _, err := im.cache.AnalyzerNamed(im.DefaultAnalyzer) if err != nil { return err @@ -263,11 +179,11 @@ func (im *IndexMapping) Validate() error { } // AddDocumentMapping sets a custom document mapping for the specified type -func (im *IndexMapping) AddDocumentMapping(doctype string, dm *DocumentMapping) { +func (im *IndexMappingImpl) AddDocumentMapping(doctype string, dm *DocumentMapping) { im.TypeMapping[doctype] = dm } -func (im *IndexMapping) mappingForType(docType string) *DocumentMapping { +func (im *IndexMappingImpl) mappingForType(docType string) *DocumentMapping { docMapping := im.TypeMapping[docType] if docMapping == nil { docMapping = im.DefaultMapping @@ -276,7 +192,7 @@ func (im *IndexMapping) mappingForType(docType string) *DocumentMapping { } // UnmarshalJSON offers custom unmarshaling with optional strict validation -func (im *IndexMapping) UnmarshalJSON(data []byte) error { +func (im *IndexMappingImpl) UnmarshalJSON(data []byte) error { var tmp map[string]json.RawMessage err := json.Unmarshal(data, &tmp) @@ -367,7 +283,7 @@ func (im *IndexMapping) UnmarshalJSON(data []byte) error { return nil } -func (im *IndexMapping) determineType(data interface{}) string { +func (im *IndexMappingImpl) determineType(data interface{}) string { // first see if the object implements Classifier classifier, ok := data.(Classifier) if ok { @@ -383,7 +299,7 @@ func (im *IndexMapping) determineType(data interface{}) string { return im.DefaultType } -func (im *IndexMapping) mapDocument(doc *document.Document, data interface{}) error { +func (im *IndexMappingImpl) MapDocument(doc *document.Document, data interface{}) error { docType := im.determineType(data) docMapping := im.mappingForType(docType) walkContext := im.newWalkContext(doc, docMapping) @@ -403,12 +319,12 @@ func (im *IndexMapping) mapDocument(doc *document.Document, data interface{}) er type walkContext struct { doc *document.Document - im *IndexMapping + im *IndexMappingImpl dm *DocumentMapping excludedFromAll []string } -func (im *IndexMapping) newWalkContext(doc *document.Document, dm *DocumentMapping) *walkContext { +func (im *IndexMappingImpl) newWalkContext(doc *document.Document, dm *DocumentMapping) *walkContext { return &walkContext{ doc: doc, im: im, @@ -422,7 +338,7 @@ func (im *IndexMapping) newWalkContext(doc *document.Document, dm *DocumentMappi // provided path, if one exists and it has an explicit analyzer // that is returned // nil should be an acceptable return value meaning we don't know -func (im *IndexMapping) analyzerNameForPath(path string) string { +func (im *IndexMappingImpl) AnalyzerNameForPath(path string) string { // first we look for explicit mapping on the field for _, docMapping := range im.TypeMapping { analyzerName := docMapping.analyzerNameForPath(path) @@ -452,7 +368,7 @@ func (im *IndexMapping) analyzerNameForPath(path string) string { return im.DefaultAnalyzer } -func (im *IndexMapping) analyzerNamed(name string) *analysis.Analyzer { +func (im *IndexMappingImpl) AnalyzerNamed(name string) *analysis.Analyzer { analyzer, err := im.cache.AnalyzerNamed(name) if err != nil { logger.Printf("error using analyzer named: %s", name) @@ -461,7 +377,10 @@ func (im *IndexMapping) analyzerNamed(name string) *analysis.Analyzer { return analyzer } -func (im *IndexMapping) dateTimeParserNamed(name string) analysis.DateTimeParser { +func (im *IndexMappingImpl) DateTimeParserNamed(name string) analysis.DateTimeParser { + if name == "" { + name = im.DefaultDateTimeParser + } dateTimeParser, err := im.cache.DateTimeParserNamed(name) if err != nil { logger.Printf("error using datetime parser named: %s", name) @@ -470,7 +389,7 @@ func (im *IndexMapping) dateTimeParserNamed(name string) analysis.DateTimeParser return dateTimeParser } -func (im *IndexMapping) datetimeParserNameForPath(path string) string { +func (im *IndexMappingImpl) datetimeParserNameForPath(path string) string { // first we look for explicit mapping on the field for _, docMapping := range im.TypeMapping { @@ -487,7 +406,7 @@ func (im *IndexMapping) datetimeParserNameForPath(path string) string { return im.DefaultDateTimeParser } -func (im *IndexMapping) AnalyzeText(analyzerName string, text []byte) (analysis.TokenStream, error) { +func (im *IndexMappingImpl) AnalyzeText(analyzerName string, text []byte) (analysis.TokenStream, error) { analyzer, err := im.cache.AnalyzerNamed(analyzerName) if err != nil { return nil, err @@ -496,6 +415,12 @@ func (im *IndexMapping) AnalyzeText(analyzerName string, text []byte) (analysis. } // FieldAnalyzer returns the name of the analyzer used on a field. -func (im *IndexMapping) FieldAnalyzer(field string) string { - return im.analyzerNameForPath(field) +func (im *IndexMappingImpl) FieldAnalyzer(field string) string { + return im.AnalyzerNameForPath(field) +} + +// wrapper to satisfy new interface + +func (im *IndexMappingImpl) DefaultSearchField() string { + return im.DefaultField } diff --git a/mapping/mapping.go b/mapping/mapping.go new file mode 100644 index 00000000..509a5380 --- /dev/null +++ b/mapping/mapping.go @@ -0,0 +1,44 @@ +// 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. + +package mapping + +import ( + "io/ioutil" + "log" + + "github.com/blevesearch/bleve/analysis" + "github.com/blevesearch/bleve/document" +) + +// A Classifier is an interface describing any object +// which knows how to identify its own type. +type Classifier interface { + Type() string +} + +var logger = log.New(ioutil.Discard, "bleve mapping ", log.LstdFlags) + +// SetLog sets the logger used for logging +// by default log messages are sent to ioutil.Discard +func SetLog(l *log.Logger) { + logger = l +} + +type IndexMapping interface { + MapDocument(doc *document.Document, data interface{}) error + Validate() error + + DateTimeParserNamed(name string) analysis.DateTimeParser + + DefaultSearchField() string + + AnalyzerNameForPath(path string) string + AnalyzerNamed(name string) *analysis.Analyzer +} diff --git a/mapping_test.go b/mapping/mapping_test.go similarity index 95% rename from mapping_test.go rename to mapping/mapping_test.go index a5eda3df..6c9b7237 100644 --- a/mapping_test.go +++ b/mapping/mapping_test.go @@ -7,7 +7,7 @@ // either express or implied. See the License for the specific language governing permissions // and limitations under the License. -package bleve +package mapping import ( "encoding/json" @@ -46,7 +46,7 @@ var mappingSource = []byte(`{ "default_type": "_default" }`) -func buildMapping() *IndexMapping { +func buildMapping() IndexMapping { nameFieldMapping := NewTextFieldMapping() nameFieldMapping.Name = "name" nameFieldMapping.Analyzer = "standard" @@ -66,7 +66,7 @@ func buildMapping() *IndexMapping { func TestUnmarshalMappingJSON(t *testing.T) { mapping := buildMapping() - var indexMapping IndexMapping + var indexMapping IndexMappingImpl err := json.Unmarshal(mappingSource, &indexMapping) if err != nil { t.Fatal(err) @@ -88,7 +88,7 @@ func TestMappingStructWithJSONTags(t *testing.T) { } doc := document.NewDocument("1") - err := mapping.mapDocument(doc, x) + err := mapping.MapDocument(doc, x) if err != nil { t.Fatal(err) } @@ -128,7 +128,7 @@ func TestMappingStructWithJSONTagsOneDisabled(t *testing.T) { } doc := document.NewDocument("1") - err := mapping.mapDocument(doc, x) + err := mapping.MapDocument(doc, x) if err != nil { t.Fatal(err) } @@ -168,7 +168,7 @@ func TestMappingStructWithPointerToString(t *testing.T) { } doc := document.NewDocument("1") - err := mapping.mapDocument(doc, x) + err := mapping.MapDocument(doc, x) if err != nil { t.Fatal(err) } @@ -200,7 +200,7 @@ func TestMappingJSONWithNull(t *testing.T) { } doc := document.NewDocument("1") - err = mapping.mapDocument(doc, jsondoc) + err = mapping.MapDocument(doc, jsondoc) if err != nil { t.Fatal(err) } @@ -243,17 +243,17 @@ func TestMappingForPath(t *testing.T) { mapping := NewIndexMapping() mapping.AddDocumentMapping("a", docMappingA) - analyzerName := mapping.analyzerNameForPath("name") + analyzerName := mapping.AnalyzerNameForPath("name") if analyzerName != enFieldMapping.Analyzer { t.Errorf("expected '%s' got '%s'", enFieldMapping.Analyzer, analyzerName) } - analyzerName = mapping.analyzerNameForPath("nameCustom") + analyzerName = mapping.AnalyzerNameForPath("nameCustom") if analyzerName != customMapping.Analyzer { t.Errorf("expected '%s' got '%s'", customMapping.Analyzer, analyzerName) } - analyzerName = mapping.analyzerNameForPath("child.desc") + analyzerName = mapping.AnalyzerNameForPath("child.desc") if analyzerName != customFieldX.Analyzer { t.Errorf("expected '%s' got '%s'", customFieldX.Analyzer, analyzerName) } @@ -345,7 +345,7 @@ func TestEnablingDisablingStoringDynamicFields(t *testing.T) { } doc := document.NewDocument("x") mapping := NewIndexMapping() - err := mapping.mapDocument(doc, data) + err := mapping.MapDocument(doc, data) if err != nil { t.Fatal(err) } @@ -363,7 +363,7 @@ func TestEnablingDisablingStoringDynamicFields(t *testing.T) { mapping = NewIndexMapping() doc = document.NewDocument("y") - err = mapping.mapDocument(doc, data) + err = mapping.MapDocument(doc, data) if err != nil { t.Fatal(err) } @@ -377,7 +377,7 @@ func TestEnablingDisablingStoringDynamicFields(t *testing.T) { mapping = NewIndexMapping() mapping.StoreDynamic = true doc = document.NewDocument("y") - err = mapping.mapDocument(doc, data) + err = mapping.MapDocument(doc, data) if err != nil { t.Fatal(err) } @@ -405,7 +405,7 @@ func TestMappingBool(t *testing.T) { } doc := document.NewDocument("1") - err := mapping.mapDocument(doc, x) + err := mapping.MapDocument(doc, x) if err != nil { t.Fatal(err) } @@ -441,7 +441,7 @@ func TestDisableDefaultMapping(t *testing.T) { } doc := document.NewDocument("x") - err := indexMapping.mapDocument(doc, data) + err := indexMapping.MapDocument(doc, data) if err != nil { t.Error(err) } @@ -526,7 +526,7 @@ func TestInvalidIndexMappingStrict(t *testing.T) { mappingBytes := []byte(`{"typeField":"type","default_field":"all"}`) // first unmarhsal it without strict - var im IndexMapping + var im IndexMappingImpl err := json.Unmarshal(mappingBytes, &im) if err != nil { t.Fatal(err) @@ -590,7 +590,7 @@ func TestMappingBug353(t *testing.T) { mapping.DefaultMapping.AddSubDocumentMapping("Other", otherMapping) doc := document.NewDocument("x") - err = mapping.mapDocument(doc, data) + err = mapping.MapDocument(doc, data) if err != nil { t.Fatal(err) } @@ -636,7 +636,7 @@ func TestAnonymousStructFields(t *testing.T) { doc := document.NewDocument("1") m := NewIndexMapping() - err := m.mapDocument(doc, x) + err := m.MapDocument(doc, x) if err != nil { t.Fatal(err) } @@ -676,7 +676,7 @@ func TestAnonymousStructFields(t *testing.T) { } doc2 := document.NewDocument("2") - err = m.mapDocument(doc2, y) + err = m.MapDocument(doc2, y) if err != nil { t.Fatal(err) } @@ -712,7 +712,7 @@ func TestAnonymousStructFieldWithJSONStructTagEmptString(t *testing.T) { doc := document.NewDocument("1") m := NewIndexMapping() - err := m.mapDocument(doc, x) + err := m.MapDocument(doc, x) if err != nil { t.Fatal(err) } @@ -749,7 +749,7 @@ func TestMappingPrimitives(t *testing.T) { m := NewIndexMapping() for _, test := range tests { doc := document.NewDocument("x") - err := m.mapDocument(doc, test.data) + err := m.MapDocument(doc, test.data) if err != nil { t.Fatal(err) } diff --git a/reflect.go b/mapping/reflect.go similarity index 99% rename from reflect.go rename to mapping/reflect.go index 21fe397a..76451857 100644 --- a/reflect.go +++ b/mapping/reflect.go @@ -7,7 +7,7 @@ // either express or implied. See the License for the specific language governing permissions // and limitations under the License. -package bleve +package mapping import ( "reflect" diff --git a/query.go b/query.go index 595c7838..3af5f451 100644 --- a/query.go +++ b/query.go @@ -14,6 +14,7 @@ import ( "fmt" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" ) @@ -24,7 +25,7 @@ type Query interface { SetBoost(b float64) Query Field() string SetField(f string) Query - Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) + Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) Validate() error } @@ -251,7 +252,7 @@ func ParseQuery(input []byte) (Query, error) { // expandQuery traverses the input query tree and returns a new tree where // query string queries have been expanded into base queries. Returned tree may // reference queries from the input tree or new queries. -func expandQuery(m *IndexMapping, query Query) (Query, error) { +func expandQuery(m mapping.IndexMapping, query Query) (Query, error) { var expand func(query Query) (Query, error) var expandSlice func(queries []Query) ([]Query, error) @@ -326,7 +327,7 @@ func expandQuery(m *IndexMapping, query Query) (Query, error) { // DumpQuery returns a string representation of the query tree, where query // string queries have been expanded into base queries. The output format is // meant for debugging purpose and may change in the future. -func DumpQuery(m *IndexMapping, query Query) (string, error) { +func DumpQuery(m mapping.IndexMapping, query Query) (string, error) { q, err := expandQuery(m, query) if err != nil { return "", err diff --git a/query_bool_field.go b/query_bool_field.go index ed3ac85f..16545994 100644 --- a/query_bool_field.go +++ b/query_bool_field.go @@ -11,6 +11,7 @@ package bleve import ( "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -47,10 +48,10 @@ func (q *boolFieldQuery) SetField(f string) Query { return q } -func (q *boolFieldQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *boolFieldQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } term := "F" if q.Bool { diff --git a/query_boolean.go b/query_boolean.go index 8dcb8efb..2fa2186e 100644 --- a/query_boolean.go +++ b/query_boolean.go @@ -14,6 +14,7 @@ import ( "fmt" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -95,7 +96,7 @@ func (q *booleanQuery) SetBoost(b float64) Query { return q } -func (q *booleanQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *booleanQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { var err error var mustNotSearcher search.Searcher if q.MustNot != nil { diff --git a/query_conjunction.go b/query_conjunction.go index 99ad71c7..1c01e668 100644 --- a/query_conjunction.go +++ b/query_conjunction.go @@ -13,6 +13,7 @@ import ( "encoding/json" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -45,7 +46,7 @@ func (q *conjunctionQuery) AddQuery(aq Query) *conjunctionQuery { return q } -func (q *conjunctionQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *conjunctionQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { ss := make([]search.Searcher, len(q.Conjuncts)) for in, conjunct := range q.Conjuncts { var err error diff --git a/query_date_range.go b/query_date_range.go index df0de333..7f84d3dc 100644 --- a/query_date_range.go +++ b/query_date_range.go @@ -14,6 +14,7 @@ import ( "math" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/numeric_util" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" @@ -71,7 +72,7 @@ func (q *dateRangeQuery) SetField(f string) Query { return q } -func (q *dateRangeQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *dateRangeQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { min, max, err := q.parseEndpoints() if err != nil { @@ -80,7 +81,7 @@ func (q *dateRangeQuery) Searcher(i index.IndexReader, m *IndexMapping, explain field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } return searchers.NewNumericRangeSearcher(i, min, max, q.InclusiveStart, q.InclusiveEnd, field, q.BoostVal, explain) diff --git a/query_disjunction.go b/query_disjunction.go index 78e4bd92..be272ea3 100644 --- a/query_disjunction.go +++ b/query_disjunction.go @@ -13,6 +13,7 @@ import ( "encoding/json" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -65,7 +66,7 @@ func (q *disjunctionQuery) SetMin(m float64) Query { return q } -func (q *disjunctionQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *disjunctionQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { ss := make([]search.Searcher, len(q.Disjuncts)) for in, disjunct := range q.Disjuncts { var err error diff --git a/query_docid.go b/query_docid.go index dce12bd4..5935eaa9 100644 --- a/query_docid.go +++ b/query_docid.go @@ -11,6 +11,7 @@ package bleve import ( "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -47,7 +48,7 @@ func (q *docIDQuery) SetField(f string) Query { return q } -func (q *docIDQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *docIDQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { return searchers.NewDocIDSearcher(i, q.IDs, q.BoostVal, explain) } diff --git a/query_fuzzy.go b/query_fuzzy.go index 2818035a..7644d643 100644 --- a/query_fuzzy.go +++ b/query_fuzzy.go @@ -11,6 +11,7 @@ package bleve import ( "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -75,10 +76,10 @@ func (q *fuzzyQuery) SetPrefix(p int) Query { return q } -func (q *fuzzyQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *fuzzyQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } return searchers.NewFuzzySearcher(i, q.Term, q.PrefixVal, q.FuzzinessVal, field, q.BoostVal, explain) } diff --git a/query_match.go b/query_match.go index 79ea3bcf..b13083a3 100644 --- a/query_match.go +++ b/query_match.go @@ -14,6 +14,7 @@ import ( "fmt" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" ) @@ -145,20 +146,20 @@ func (q *matchQuery) SetOperator(operator MatchQueryOperator) Query { return q } -func (q *matchQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *matchQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } analyzerName := "" if q.Analyzer != "" { analyzerName = q.Analyzer } else { - analyzerName = m.analyzerNameForPath(field) + analyzerName = m.AnalyzerNameForPath(field) } - analyzer := m.analyzerNamed(analyzerName) + analyzer := m.AnalyzerNamed(analyzerName) if analyzer == nil { return nil, fmt.Errorf("no analyzer named '%s' registered", q.Analyzer) diff --git a/query_match_all.go b/query_match_all.go index 02232bcd..2ae2acb3 100644 --- a/query_match_all.go +++ b/query_match_all.go @@ -13,6 +13,7 @@ import ( "encoding/json" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -38,7 +39,7 @@ func (q *matchAllQuery) SetBoost(b float64) Query { return q } -func (q *matchAllQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *matchAllQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { return searchers.NewMatchAllSearcher(i, q.BoostVal, explain) } diff --git a/query_match_none.go b/query_match_none.go index b13ca6c8..14fddab5 100644 --- a/query_match_none.go +++ b/query_match_none.go @@ -13,6 +13,7 @@ import ( "encoding/json" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -38,7 +39,7 @@ func (q *matchNoneQuery) SetBoost(b float64) Query { return q } -func (q *matchNoneQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *matchNoneQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { return searchers.NewMatchNoneSearcher(i) } diff --git a/query_match_phrase.go b/query_match_phrase.go index 8deed182..1d588628 100644 --- a/query_match_phrase.go +++ b/query_match_phrase.go @@ -14,6 +14,7 @@ import ( "github.com/blevesearch/bleve/analysis" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" ) @@ -57,19 +58,19 @@ func (q *matchPhraseQuery) SetField(f string) Query { return q } -func (q *matchPhraseQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *matchPhraseQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } analyzerName := "" if q.Analyzer != "" { analyzerName = q.Analyzer } else { - analyzerName = m.analyzerNameForPath(field) + analyzerName = m.AnalyzerNameForPath(field) } - analyzer := m.analyzerNamed(analyzerName) + analyzer := m.AnalyzerNamed(analyzerName) if analyzer == nil { return nil, fmt.Errorf("no analyzer named '%s' registered", q.Analyzer) } diff --git a/query_numeric_range.go b/query_numeric_range.go index 87d5f348..973b9cb3 100644 --- a/query_numeric_range.go +++ b/query_numeric_range.go @@ -11,6 +11,7 @@ package bleve import ( "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -65,10 +66,10 @@ func (q *numericRangeQuery) SetField(f string) Query { return q } -func (q *numericRangeQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *numericRangeQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } return searchers.NewNumericRangeSearcher(i, q.Min, q.Max, q.InclusiveMin, q.InclusiveMax, field, q.BoostVal, explain) } diff --git a/query_phrase.go b/query_phrase.go index bfc2e245..9f8df326 100644 --- a/query_phrase.go +++ b/query_phrase.go @@ -13,6 +13,7 @@ import ( "encoding/json" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -54,7 +55,7 @@ func (q *phraseQuery) SetBoost(b float64) Query { return q } -func (q *phraseQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *phraseQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { conjunctionQuery := NewConjunctionQuery(q.termQueries) conjunctionSearcher, err := conjunctionQuery.Searcher(i, m, explain) diff --git a/query_prefix.go b/query_prefix.go index 8d032e54..a3710a1c 100644 --- a/query_prefix.go +++ b/query_prefix.go @@ -11,6 +11,7 @@ package bleve import ( "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -49,10 +50,10 @@ func (q *prefixQuery) SetField(f string) Query { return q } -func (q *prefixQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *prefixQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } return searchers.NewTermPrefixSearcher(i, q.Prefix, field, q.BoostVal, explain) } diff --git a/query_regexp.go b/query_regexp.go index 06144c12..89e0e7c4 100644 --- a/query_regexp.go +++ b/query_regexp.go @@ -14,6 +14,7 @@ import ( "strings" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -53,10 +54,10 @@ func (q *regexpQuery) SetField(f string) Query { return q } -func (q *regexpQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *regexpQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } err := q.compile() if err != nil { diff --git a/query_string.go b/query_string.go index 005191cd..eed878b5 100644 --- a/query_string.go +++ b/query_string.go @@ -11,6 +11,7 @@ package bleve import ( "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" ) @@ -38,7 +39,7 @@ func (q *queryStringQuery) SetBoost(b float64) Query { return q } -func (q *queryStringQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *queryStringQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { newQuery, err := parseQuerySyntax(q.Query) if err != nil { return nil, err diff --git a/query_string_parser_test.go b/query_string_parser_test.go index cef9be3b..68a4b27d 100644 --- a/query_string_parser_test.go +++ b/query_string_parser_test.go @@ -13,6 +13,8 @@ import ( "reflect" "strings" "testing" + + "github.com/blevesearch/bleve/mapping" ) func TestQuerySyntaxParserValid(t *testing.T) { @@ -23,7 +25,7 @@ func TestQuerySyntaxParserValid(t *testing.T) { tests := []struct { input string result Query - mapping *IndexMapping + mapping mapping.IndexMapping }{ { input: "test", diff --git a/query_term.go b/query_term.go index df92b454..683cdf1e 100644 --- a/query_term.go +++ b/query_term.go @@ -11,6 +11,7 @@ package bleve import ( "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -48,10 +49,10 @@ func (q *termQuery) SetField(f string) Query { return q } -func (q *termQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *termQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } return searchers.NewTermSearcher(i, q.Term, field, q.BoostVal, explain) } diff --git a/query_test.go b/query_test.go index 5cd4f3ea..e7b39876 100644 --- a/query_test.go +++ b/query_test.go @@ -268,7 +268,7 @@ func TestQueryValidate(t *testing.T) { } func TestDumpQuery(t *testing.T) { - mapping := &IndexMapping{} + mapping := NewIndexMapping() q := NewQueryStringQuery("+water -light beer") s, err := DumpQuery(mapping, q) if err != nil { diff --git a/query_wildcard.go b/query_wildcard.go index 32fd3433..7b713454 100644 --- a/query_wildcard.go +++ b/query_wildcard.go @@ -14,6 +14,7 @@ import ( "strings" "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" "github.com/blevesearch/bleve/search" "github.com/blevesearch/bleve/search/searchers" ) @@ -74,10 +75,10 @@ func (q *wildcardQuery) SetField(f string) Query { return q } -func (q *wildcardQuery) Searcher(i index.IndexReader, m *IndexMapping, explain bool) (search.Searcher, error) { +func (q *wildcardQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) { field := q.FieldVal if q.FieldVal == "" { - field = m.DefaultField + field = m.DefaultSearchField() } if q.compiled == nil { var err error diff --git a/test/integration_test.go b/test/integration_test.go index ad280e27..3cb03da2 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -24,6 +24,7 @@ import ( // we must explicitly include any functionality we plan on testing _ "github.com/blevesearch/bleve/analysis/analyzers/keyword_analyzer" + "github.com/blevesearch/bleve/mapping" // allow choosing alternate kvstores _ "github.com/blevesearch/bleve/config" @@ -77,7 +78,7 @@ func runTestDir(t *testing.T, dir, datasetName string) { t.Errorf("error reading mapping: %v", err) return } - var mapping bleve.IndexMapping + var mapping mapping.IndexMappingImpl err = json.Unmarshal(mappingBytes, &mapping) if err != nil { t.Errorf("error unmarshalling mapping: %v", err)