refactored field from struct to interface
This commit is contained in:
parent
f225d484b3
commit
d3466f3919
|
@ -13,18 +13,18 @@ import (
|
|||
)
|
||||
|
||||
type Document struct {
|
||||
ID string `json:"id"`
|
||||
Fields []*Field `json:"fields"`
|
||||
ID string `json:"id"`
|
||||
Fields []Field `json:"fields"`
|
||||
}
|
||||
|
||||
func NewDocument(id string) *Document {
|
||||
return &Document{
|
||||
ID: id,
|
||||
Fields: make([]*Field, 0),
|
||||
Fields: make([]Field, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Document) AddField(f *Field) *Document {
|
||||
func (d *Document) AddField(f Field) *Document {
|
||||
d.Fields = append(d.Fields, f)
|
||||
return d
|
||||
}
|
||||
|
|
|
@ -12,18 +12,9 @@ import (
|
|||
"github.com/couchbaselabs/bleve/analysis"
|
||||
)
|
||||
|
||||
type Field struct {
|
||||
Name string
|
||||
Options IndexingOptions
|
||||
Analyzer *analysis.Analyzer
|
||||
Value []byte
|
||||
}
|
||||
|
||||
func NewField(name string, value []byte, options IndexingOptions, analyzer *analysis.Analyzer) *Field {
|
||||
return &Field{
|
||||
Name: name,
|
||||
Options: options,
|
||||
Analyzer: analyzer,
|
||||
Value: value,
|
||||
}
|
||||
type Field interface {
|
||||
Name() string
|
||||
Options() IndexingOptions
|
||||
Analyzer() *analysis.Analyzer
|
||||
Value() []byte
|
||||
}
|
||||
|
|
|
@ -27,15 +27,47 @@ func init() {
|
|||
|
||||
const DEFAULT_TEXT_INDEXING_OPTIONS = INDEX_FIELD
|
||||
|
||||
func NewTextField(name string, value []byte) *Field {
|
||||
type TextField struct {
|
||||
name string
|
||||
options IndexingOptions
|
||||
analyzer *analysis.Analyzer
|
||||
value []byte
|
||||
}
|
||||
|
||||
func (t *TextField) Name() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
func (t *TextField) Options() IndexingOptions {
|
||||
return t.options
|
||||
}
|
||||
|
||||
func (t *TextField) Analyzer() *analysis.Analyzer {
|
||||
return t.analyzer
|
||||
}
|
||||
|
||||
func (t *TextField) Value() []byte {
|
||||
return t.value
|
||||
}
|
||||
|
||||
func NewTextField(name string, value []byte) *TextField {
|
||||
return NewTextFieldWithIndexingOptions(name, value, DEFAULT_TEXT_INDEXING_OPTIONS)
|
||||
}
|
||||
|
||||
func NewTextFieldWithIndexingOptions(name string, value []byte, options IndexingOptions) *Field {
|
||||
return &Field{
|
||||
Name: name,
|
||||
Options: options,
|
||||
Analyzer: standardAnalyzer,
|
||||
Value: value,
|
||||
func NewTextFieldWithIndexingOptions(name string, value []byte, options IndexingOptions) *TextField {
|
||||
return &TextField{
|
||||
name: name,
|
||||
options: options,
|
||||
analyzer: standardAnalyzer,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTextFieldCustom(name string, value []byte, options IndexingOptions, analyzer *analysis.Analyzer) *TextField {
|
||||
return &TextField{
|
||||
name: name,
|
||||
options: options,
|
||||
analyzer: analyzer,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,29 +265,29 @@ func (udc *UpsideDownCouch) Update(doc *document.Document) error {
|
|||
backIndexStoredFields := make([]uint16, 0)
|
||||
|
||||
for _, field := range doc.Fields {
|
||||
fieldIndex, fieldExists := udc.fieldIndexes[field.Name]
|
||||
fieldIndex, fieldExists := udc.fieldIndexes[field.Name()]
|
||||
if !fieldExists {
|
||||
// assign next field id
|
||||
fieldIndex = uint16(udc.lastFieldIndex + 1)
|
||||
udc.fieldIndexes[field.Name] = fieldIndex
|
||||
udc.fieldIndexes[field.Name()] = fieldIndex
|
||||
// ensure this batch adds a row for this field
|
||||
row := NewFieldRow(uint16(fieldIndex), field.Name)
|
||||
row := NewFieldRow(uint16(fieldIndex), field.Name())
|
||||
updateRows = append(updateRows, row)
|
||||
udc.lastFieldIndex = int(fieldIndex)
|
||||
}
|
||||
|
||||
existingTermMap, fieldExistedInDoc := existingTermFieldMaps[int(fieldIndex)]
|
||||
|
||||
if field.Options.IsIndexed() {
|
||||
if field.Options().IsIndexed() {
|
||||
|
||||
analyzer := field.Analyzer
|
||||
tokens := analyzer.Analyze(field.Value)
|
||||
analyzer := field.Analyzer()
|
||||
tokens := analyzer.Analyze(field.Value())
|
||||
fieldLength := len(tokens) // number of tokens in this doc field
|
||||
fieldNorm := float32(1.0 / math.Sqrt(float64(fieldLength)))
|
||||
tokenFreqs := analysis.TokenFrequency(tokens)
|
||||
for _, tf := range tokenFreqs {
|
||||
var termFreqRow *TermFrequencyRow
|
||||
if field.Options.IncludeTermVectors() {
|
||||
if field.Options().IncludeTermVectors() {
|
||||
tv := termVectorsFromTokenFreq(uint16(fieldIndex), tf)
|
||||
termFreqRow = NewTermFrequencyRowWithTermVectors(tf.Term, uint16(fieldIndex), doc.ID, uint64(frequencyFromTokenFreq(tf)), fieldNorm, tv)
|
||||
} else {
|
||||
|
@ -318,8 +318,8 @@ func (udc *UpsideDownCouch) Update(doc *document.Document) error {
|
|||
}
|
||||
}
|
||||
|
||||
if field.Options.IsStored() {
|
||||
storedRow := NewStoredRow(doc.ID, uint16(fieldIndex), field.Value)
|
||||
if field.Options().IsStored() {
|
||||
storedRow := NewStoredRow(doc.ID, uint16(fieldIndex), field.Value())
|
||||
backIndexStoredFields = append(backIndexStoredFields, fieldIndex)
|
||||
_, ok := existingStoredFieldMap[uint16(fieldIndex)]
|
||||
if ok {
|
||||
|
@ -502,10 +502,7 @@ func (udc *UpsideDownCouch) Document(id string) (*document.Document, error) {
|
|||
return nil, err
|
||||
}
|
||||
if row != nil {
|
||||
rv.AddField(&document.Field{
|
||||
Name: udc.fieldIndexToName(row.field),
|
||||
Value: row.Value(),
|
||||
})
|
||||
rv.AddField(document.NewTextField(udc.fieldIndexToName(row.field), row.Value()))
|
||||
}
|
||||
|
||||
it.Next()
|
||||
|
|
|
@ -312,7 +312,7 @@ func TestIndexInsertWithStore(t *testing.T) {
|
|||
if len(storedDoc.Fields) != 1 {
|
||||
t.Errorf("expected 1 stored field, got %d", len(storedDoc.Fields))
|
||||
}
|
||||
if string(storedDoc.Fields[0].Value) != "test" {
|
||||
t.Errorf("expected field content 'test', got '%s'", string(storedDoc.Fields[0].Value))
|
||||
if string(storedDoc.Fields[0].Value()) != "test" {
|
||||
t.Errorf("expected field content 'test', got '%s'", string(storedDoc.Fields[0].Value()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ func (s *SimpleHighlighter) BestFragmentsInField(dm *DocumentMatch, doc *documen
|
|||
fq := make(FragmentQueue, 0)
|
||||
heap.Init(&fq)
|
||||
for _, f := range doc.Fields {
|
||||
if f.Name == field {
|
||||
fieldData := f.Value
|
||||
if f.Name() == field {
|
||||
fieldData := f.Value()
|
||||
fragments := s.fragmenter.Fragment(fieldData, orderedTermLocations)
|
||||
for _, fragment := range fragments {
|
||||
scorer.Score(fragment)
|
||||
|
|
|
@ -30,61 +30,61 @@ func TestTermSearcher(t *testing.T) {
|
|||
i := upside_down.NewUpsideDownCouch(inMemStore)
|
||||
i.Update(&document.Document{
|
||||
ID: "a",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "b",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "c",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "d",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "e",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "f",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "g",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "h",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "i",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("desc", []byte("beer")),
|
||||
},
|
||||
})
|
||||
i.Update(&document.Document{
|
||||
ID: "j",
|
||||
Fields: []*document.Field{
|
||||
Fields: []document.Field{
|
||||
document.NewTextField("title", []byte("cat")),
|
||||
},
|
||||
})
|
||||
|
|
|
@ -67,7 +67,7 @@ func (s *JsonPointerShredder) Shred(id string, body []byte) (*document.Document,
|
|||
analyzer, custom := s.analyzers[fieldName]
|
||||
if custom {
|
||||
options := s.options[fieldName]
|
||||
field := document.NewField(fieldName, fieldValue, options, analyzer)
|
||||
field := document.NewTextFieldCustom(fieldName, fieldValue, options, analyzer)
|
||||
rv.AddField(field)
|
||||
} else {
|
||||
field := document.NewTextField(fieldName, fieldValue)
|
||||
|
|
Loading…
Reference in New Issue