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 15package document 16 17import ( 18 "fmt" 19 20 "github.com/blevesearch/bleve/analysis" 21 "github.com/blevesearch/bleve/numeric" 22) 23 24const DefaultNumericIndexingOptions = StoreField | IndexField | DocValues 25 26const DefaultPrecisionStep uint = 4 27 28type NumericField struct { 29 name string 30 arrayPositions []uint64 31 options IndexingOptions 32 value numeric.PrefixCoded 33 numPlainTextBytes uint64 34} 35 36func (n *NumericField) Name() string { 37 return n.name 38} 39 40func (n *NumericField) ArrayPositions() []uint64 { 41 return n.arrayPositions 42} 43 44func (n *NumericField) Options() IndexingOptions { 45 return n.options 46} 47 48func (n *NumericField) Analyze() (int, analysis.TokenFrequencies) { 49 tokens := make(analysis.TokenStream, 0) 50 tokens = append(tokens, &analysis.Token{ 51 Start: 0, 52 End: len(n.value), 53 Term: n.value, 54 Position: 1, 55 Type: analysis.Numeric, 56 }) 57 58 original, err := n.value.Int64() 59 if err == nil { 60 61 shift := DefaultPrecisionStep 62 for shift < 64 { 63 shiftEncoded, err := numeric.NewPrefixCodedInt64(original, shift) 64 if err != nil { 65 break 66 } 67 token := analysis.Token{ 68 Start: 0, 69 End: len(shiftEncoded), 70 Term: shiftEncoded, 71 Position: 1, 72 Type: analysis.Numeric, 73 } 74 tokens = append(tokens, &token) 75 shift += DefaultPrecisionStep 76 } 77 } 78 79 fieldLength := len(tokens) 80 tokenFreqs := analysis.TokenFrequency(tokens, n.arrayPositions, n.options.IncludeTermVectors()) 81 return fieldLength, tokenFreqs 82} 83 84func (n *NumericField) Value() []byte { 85 return n.value 86} 87 88func (n *NumericField) Number() (float64, error) { 89 i64, err := n.value.Int64() 90 if err != nil { 91 return 0.0, err 92 } 93 return numeric.Int64ToFloat64(i64), nil 94} 95 96func (n *NumericField) GoString() string { 97 return fmt.Sprintf("&document.NumericField{Name:%s, Options: %s, Value: %s}", n.name, n.options, n.value) 98} 99 100func (n *NumericField) NumPlainTextBytes() uint64 { 101 return n.numPlainTextBytes 102} 103 104func NewNumericFieldFromBytes(name string, arrayPositions []uint64, value []byte) *NumericField { 105 return &NumericField{ 106 name: name, 107 arrayPositions: arrayPositions, 108 value: value, 109 options: DefaultNumericIndexingOptions, 110 numPlainTextBytes: uint64(len(value)), 111 } 112} 113 114func NewNumericField(name string, arrayPositions []uint64, number float64) *NumericField { 115 return NewNumericFieldWithIndexingOptions(name, arrayPositions, number, DefaultNumericIndexingOptions) 116} 117 118func NewNumericFieldWithIndexingOptions(name string, arrayPositions []uint64, number float64, options IndexingOptions) *NumericField { 119 numberInt64 := numeric.Float64ToInt64(number) 120 prefixCoded := numeric.MustNewPrefixCodedInt64(numberInt64, 0) 121 return &NumericField{ 122 name: name, 123 arrayPositions: arrayPositions, 124 value: prefixCoded, 125 options: options, 126 // not correct, just a place holder until we revisit how fields are 127 // represented and can fix this better 128 numPlainTextBytes: uint64(8), 129 } 130} 131