0
0

fixed bug with internal get/set/delete, added tests

This commit is contained in:
Marty Schoch 2014-08-15 09:39:41 -04:00
parent 6b7c12b8bd
commit 4d53db9fc8
2 changed files with 594 additions and 103 deletions

View File

@ -506,27 +506,6 @@ func (udc *UpsideDownCouch) backIndexRowsForBatch(batch index.Batch) (map[string
return rv, nil
}
func (udc *UpsideDownCouch) Dump() {
it := udc.store.Iterator([]byte{0})
defer it.Close()
key, val, valid := it.Current()
for valid {
row, err := ParseFromKeyValue(key, val)
if err != nil {
fmt.Printf("error parsing key/value: %v", err)
return
}
if row != nil {
fmt.Printf("%v\n", row)
fmt.Printf("Key: % -100x\nValue: % -100x\n\n", key, val)
}
it.Next()
key, val, valid = it.Current()
}
}
func (udc *UpsideDownCouch) Fields() ([]string, error) {
rv := make([]string, 0)
it := udc.store.Iterator([]byte{'f'})
@ -553,71 +532,6 @@ func (udc *UpsideDownCouch) Fields() ([]string, error) {
return rv, nil
}
func (udc *UpsideDownCouch) DumpFields() {
it := udc.store.Iterator([]byte{'f'})
defer it.Close()
key, val, valid := it.Current()
for valid {
if !bytes.HasPrefix(key, []byte{'f'}) {
break
}
row, err := ParseFromKeyValue(key, val)
if err != nil {
fmt.Printf("error parsing key/value: %v", err)
return
}
if row != nil {
fmt.Printf("%v\n", row)
fmt.Printf("Key: % -100x\nValue: % -100x\n\n", key, val)
}
it.Next()
key, val, valid = it.Current()
}
}
type keyset [][]byte
func (k keyset) Len() int { return len(k) }
func (k keyset) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
func (k keyset) Less(i, j int) bool { return bytes.Compare(k[i], k[j]) < 0 }
// DumpDoc returns all rows in the index related to this doc id
func (udc *UpsideDownCouch) DumpDoc(id string) ([]interface{}, error) {
rv := make([]interface{}, 0)
back, err := udc.backIndexRowForDoc(id)
if err != nil {
return nil, err
}
keys := make(keyset, 0)
for _, stored := range back.storedFields {
sr := NewStoredRow(id, stored, 'x', []byte{})
key := sr.Key()
keys = append(keys, key)
}
for _, entry := range back.entries {
tfr := NewTermFrequencyRow(entry.term, entry.field, id, 0, 0)
key := tfr.Key()
keys = append(keys, key)
}
sort.Sort(keys)
for _, key := range keys {
value, err := udc.store.Get(key)
if err != nil {
return nil, err
}
row, err := ParseFromKeyValue(key, value)
if err != nil {
return nil, err
}
rv = append(rv, row)
}
return rv, nil
}
func (udc *UpsideDownCouch) TermFieldReader(term []byte, fieldName string) (index.TermFieldReader, error) {
fieldIndex, fieldExists := udc.fieldIndexes[fieldName]
if fieldExists {
@ -793,17 +707,97 @@ func (udc *UpsideDownCouch) SetInternal(key, val []byte) error {
}
func (udc *UpsideDownCouch) GetInternal(key []byte) ([]byte, error) {
internalRow, err := NewInternalRowKV(key, nil)
if err != nil {
return nil, err
}
internalRow := NewInternalRow(key, nil)
return udc.store.Get(internalRow.Key())
}
func (udc *UpsideDownCouch) DeleteInternal(key []byte) error {
internalRow, err := NewInternalRowKV(key, nil)
if err != nil {
return err
}
internalRow := NewInternalRow(key, nil)
return udc.store.Delete(internalRow.Key())
}
func (udc *UpsideDownCouch) Dump() {
it := udc.store.Iterator([]byte{0})
defer it.Close()
key, val, valid := it.Current()
for valid {
row, err := ParseFromKeyValue(key, val)
if err != nil {
fmt.Printf("error parsing key/value: %v", err)
return
}
if row != nil {
fmt.Printf("%v\n", row)
fmt.Printf("Key: % -100x\nValue: % -100x\n\n", key, val)
}
it.Next()
key, val, valid = it.Current()
}
}
func (udc *UpsideDownCouch) DumpFields() {
it := udc.store.Iterator([]byte{'f'})
defer it.Close()
key, val, valid := it.Current()
for valid {
if !bytes.HasPrefix(key, []byte{'f'}) {
break
}
row, err := ParseFromKeyValue(key, val)
if err != nil {
fmt.Printf("error parsing key/value: %v", err)
return
}
if row != nil {
fmt.Printf("%v\n", row)
fmt.Printf("Key: % -100x\nValue: % -100x\n\n", key, val)
}
it.Next()
key, val, valid = it.Current()
}
}
type keyset [][]byte
func (k keyset) Len() int { return len(k) }
func (k keyset) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
func (k keyset) Less(i, j int) bool { return bytes.Compare(k[i], k[j]) < 0 }
// DumpDoc returns all rows in the index related to this doc id
func (udc *UpsideDownCouch) DumpDoc(id string) ([]interface{}, error) {
rv := make([]interface{}, 0)
back, err := udc.backIndexRowForDoc(id)
if err != nil {
return nil, err
}
keys := make(keyset, 0)
for _, stored := range back.storedFields {
sr := NewStoredRow(id, stored, 'x', []byte{})
key := sr.Key()
keys = append(keys, key)
}
for _, entry := range back.entries {
tfr := NewTermFrequencyRow(entry.term, entry.field, id, 0, 0)
key := tfr.Key()
keys = append(keys, key)
}
sort.Sort(keys)
for _, key := range keys {
value, err := udc.store.Get(key)
if err != nil {
return nil, err
}
row, err := ParseFromKeyValue(key, value)
if err != nil {
return nil, err
}
rv = append(rv, row)
}
return rv, nil
}

View File

@ -10,13 +10,16 @@ package upside_down
import (
"os"
"reflect"
"regexp"
"testing"
"time"
"github.com/couchbaselabs/bleve/analysis"
"github.com/couchbaselabs/bleve/analysis/tokenizers/regexp_tokenizer"
"github.com/couchbaselabs/bleve/document"
"github.com/couchbaselabs/bleve/index/store/gouchstore"
"github.com/couchbaselabs/bleve/index"
"github.com/couchbaselabs/bleve/index/store/leveldb"
)
var testAnalyzer = &analysis.Analyzer{
@ -26,7 +29,7 @@ var testAnalyzer = &analysis.Analyzer{
func TestIndexOpenReopen(t *testing.T) {
defer os.RemoveAll("test")
store, err := gouchstore.Open("test")
store, err := leveldb.Open("test", true)
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
@ -49,7 +52,7 @@ func TestIndexOpenReopen(t *testing.T) {
// now close it
idx.Close()
store, err = gouchstore.Open("test")
store, err = leveldb.Open("test", true)
idx = NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
@ -63,7 +66,7 @@ func TestIndexOpenReopen(t *testing.T) {
func TestIndexInsert(t *testing.T) {
defer os.RemoveAll("test")
store, err := gouchstore.Open("test")
store, err := leveldb.Open("test", true)
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
@ -101,7 +104,7 @@ func TestIndexInsert(t *testing.T) {
func TestIndexInsertThenDelete(t *testing.T) {
defer os.RemoveAll("test")
store, err := gouchstore.Open("test")
store, err := leveldb.Open("test", true)
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
@ -169,7 +172,7 @@ func TestIndexInsertThenDelete(t *testing.T) {
func TestIndexInsertThenUpdate(t *testing.T) {
defer os.RemoveAll("test")
store, err := gouchstore.Open("test")
store, err := leveldb.Open("test", true)
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
@ -218,7 +221,7 @@ func TestIndexInsertThenUpdate(t *testing.T) {
func TestIndexInsertMultiple(t *testing.T) {
defer os.RemoveAll("test")
store, err := gouchstore.Open("test")
store, err := leveldb.Open("test", true)
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
@ -252,12 +255,13 @@ func TestIndexInsertMultiple(t *testing.T) {
// close and reopen and and one more to testing counting works correctly
idx.Close()
store, err = gouchstore.Open("test")
store, err = leveldb.Open("test", true)
idx = NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
doc = document.NewDocument("3")
doc.AddField(document.NewTextField("name", []byte("test")))
@ -276,7 +280,10 @@ func TestIndexInsertMultiple(t *testing.T) {
func TestIndexInsertWithStore(t *testing.T) {
defer os.RemoveAll("test")
store, err := gouchstore.Open("test")
store, err := leveldb.Open("test", true)
if err != nil {
t.Error(err)
}
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
@ -326,3 +333,493 @@ func TestIndexInsertWithStore(t *testing.T) {
t.Errorf("expected field content 'test', got '%s'", string(textField.Value()))
}
}
func TestIndexInternalCRUD(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
// get something that doesnt exist yet
val, err := idx.GetInternal([]byte("key"))
if err != nil {
t.Error(err)
}
if val != nil {
t.Errorf("expected nil, got %s", val)
}
// set
err = idx.SetInternal([]byte("key"), []byte("abc"))
if err != nil {
t.Error(err)
}
// get
val, err = idx.GetInternal([]byte("key"))
if err != nil {
t.Error(err)
}
if string(val) != "abc" {
t.Errorf("expected %s, got '%s'", "abc", val)
}
// delete
err = idx.DeleteInternal([]byte("key"))
if err != nil {
t.Error(err)
}
// get again
val, err = idx.GetInternal([]byte("key"))
if err != nil {
t.Error(err)
}
if val != nil {
t.Errorf("expected nil, got %s", val)
}
}
func TestIndexBatch(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
var expectedCount uint64 = 0
// first create 2 docs the old fashioned way
doc := document.NewDocument("1")
doc.AddField(document.NewTextField("name", []byte("test")))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
expectedCount += 1
doc = document.NewDocument("2")
doc.AddField(document.NewTextField("name", []byte("test2")))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
expectedCount += 1
// now create a batch which does 3 things
// insert new doc
// update existing doc
// delete existing doc
// net document count change 0
batch := make(index.Batch, 0)
doc = document.NewDocument("3")
doc.AddField(document.NewTextField("name", []byte("test3")))
batch["3"] = doc
doc = document.NewDocument("2")
doc.AddField(document.NewTextField("name", []byte("test2updated")))
batch["2"] = doc
batch["1"] = nil
err = idx.Batch(batch)
if err != nil {
t.Error(err)
}
docCount := idx.DocCount()
if docCount != expectedCount {
t.Errorf("Expected document count to be %d got %d", expectedCount, docCount)
}
docIdReader, err := idx.DocIdReader("", "")
if err != nil {
t.Error(err)
}
docIds := make([]string, 0)
docId, err := docIdReader.Next()
for docId != "" && err == nil {
docIds = append(docIds, docId)
docId, err = docIdReader.Next()
}
if err != nil {
t.Error(err)
}
expectedDocIds := []string{"2", "3"}
if !reflect.DeepEqual(docIds, expectedDocIds) {
t.Errorf("expected ids: %v, got ids: %v", expectedDocIds, docIds)
}
}
func TestIndexInsertUpdateDeleteWithMultipleTypesStored(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
if err != nil {
t.Error(err)
}
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
var expectedCount uint64 = 0
docCount := idx.DocCount()
if docCount != expectedCount {
t.Errorf("Expected document count to be %d got %d", expectedCount, docCount)
}
doc := document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("test"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewNumericFieldWithIndexingOptions("age", 35.99, document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewDateTimeFieldWithIndexingOptions("unixEpoch", time.Unix(0, 0), document.INDEX_FIELD|document.STORE_FIELD))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
expectedCount += 1
docCount = idx.DocCount()
if docCount != expectedCount {
t.Errorf("Expected document count to be %d got %d", expectedCount, docCount)
}
// should have 72 rows
// 1 for version
// 3 for schema fields
// 1 for text term
// 16 for numeric terms
// 16 for date terms
// 3 for the stored field
// 1 for the text term count
// 16 for numeric term counts
// 16 for date term counts
// 1 for the back index entry
expectedLength := uint64(1 + 3 + 1 + (64 / document.DEFAULT_PRECISION_STEP) + (64 / document.DEFAULT_PRECISION_STEP) + 3 + 1 + (64 / document.DEFAULT_PRECISION_STEP) + (64 / document.DEFAULT_PRECISION_STEP) + 1)
rowCount := idx.rowCount()
if rowCount != expectedLength {
t.Errorf("expected %d rows, got: %d", expectedLength, rowCount)
}
storedDoc, err := idx.Document("1")
if err != nil {
t.Error(err)
}
if len(storedDoc.Fields) != 3 {
t.Errorf("expected 3 stored field, got %d", len(storedDoc.Fields))
}
textField, ok := storedDoc.Fields[0].(*document.TextField)
if !ok {
t.Errorf("expected text field")
}
if string(textField.Value()) != "test" {
t.Errorf("expected field content 'test', got '%s'", string(textField.Value()))
}
numField, ok := storedDoc.Fields[1].(*document.NumericField)
if !ok {
t.Errorf("expected numeric field")
}
numFieldNumer, err := numField.Number()
if err != nil {
t.Error(err)
} else {
if numFieldNumer != 35.99 {
t.Errorf("expeted numeric value 35.99, got %f", numFieldNumer)
}
}
dateField, ok := storedDoc.Fields[2].(*document.DateTimeField)
if !ok {
t.Errorf("expected date field")
}
dateFieldDate, err := dateField.DateTime()
if err != nil {
t.Error(err)
} else {
if dateFieldDate != time.Unix(0, 0) {
t.Errorf("expected date value unix epoch, got %v", dateFieldDate)
}
}
// now update the document, but omit one of the fields
doc = document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("testup"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewNumericFieldWithIndexingOptions("age", 36.99, document.INDEX_FIELD|document.STORE_FIELD))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
// expected doc count shouldn't have changed
docCount = idx.DocCount()
if docCount != expectedCount {
t.Errorf("Expected document count to be %d got %d", expectedCount, docCount)
}
// should only get 2 fields back now though
storedDoc, err = idx.Document("1")
if err != nil {
t.Error(err)
}
if len(storedDoc.Fields) != 2 {
t.Errorf("expected 3 stored field, got %d", len(storedDoc.Fields))
}
textField, ok = storedDoc.Fields[0].(*document.TextField)
if !ok {
t.Errorf("expected text field")
}
if string(textField.Value()) != "testup" {
t.Errorf("expected field content 'testup', got '%s'", string(textField.Value()))
}
numField, ok = storedDoc.Fields[1].(*document.NumericField)
if !ok {
t.Errorf("expected numeric field")
}
numFieldNumer, err = numField.Number()
if err != nil {
t.Error(err)
} else {
if numFieldNumer != 36.99 {
t.Errorf("expeted numeric value 36.99, got %f", numFieldNumer)
}
}
// now delete the document
err = idx.Delete("1")
expectedCount--
// expected doc count shouldn't have changed
docCount = idx.DocCount()
if docCount != expectedCount {
t.Errorf("Expected document count to be %d got %d", expectedCount, docCount)
}
}
func TestIndexInsertFields(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
if err != nil {
t.Error(err)
}
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
doc := document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("test"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewNumericFieldWithIndexingOptions("age", 35.99, document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewDateTimeFieldWithIndexingOptions("unixEpoch", time.Unix(0, 0), document.INDEX_FIELD|document.STORE_FIELD))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
fields, err := idx.Fields()
if err != nil {
t.Error(err)
} else {
expectedFields := []string{"name", "age", "unixEpoch"}
if !reflect.DeepEqual(fields, expectedFields) {
t.Errorf("expected fields: %v, got %v", expectedFields, fields)
}
}
}
func TestIndexUpdateComposites(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
if err != nil {
t.Error(err)
}
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
doc := document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("test"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewTextFieldWithIndexingOptions("title", []byte("mister"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewCompositeFieldWithIndexingOptions("_all", true, nil, nil, document.INDEX_FIELD))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
// should have 72 rows
// 1 for version
// 3 for schema fields
// 4 for text term
// 2 for the stored field
// 4 for the text term count
// 1 for the back index entry
expectedLength := uint64(1 + 3 + 4 + 2 + 4 + 1)
rowCount := idx.rowCount()
if rowCount != expectedLength {
t.Errorf("expected %d rows, got: %d", expectedLength, rowCount)
}
// now lets update it
doc = document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("testupdated"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewTextFieldWithIndexingOptions("title", []byte("misterupdated"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewCompositeFieldWithIndexingOptions("_all", true, nil, nil, document.INDEX_FIELD))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
// make sure new values are in index
storedDoc, err := idx.Document("1")
if err != nil {
t.Error(err)
}
if len(storedDoc.Fields) != 2 {
t.Errorf("expected 2 stored field, got %d", len(storedDoc.Fields))
}
textField, ok := storedDoc.Fields[0].(*document.TextField)
if !ok {
t.Errorf("expected text field")
}
if string(textField.Value()) != "testupdated" {
t.Errorf("expected field content 'test', got '%s'", string(textField.Value()))
}
// should have the same row count as before
rowCount = idx.rowCount()
if rowCount != expectedLength {
t.Errorf("expected %d rows, got: %d", expectedLength, rowCount)
}
}
func TestIndexFieldsMisc(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
if err != nil {
t.Error(err)
}
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
doc := document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("test"), document.INDEX_FIELD|document.STORE_FIELD))
doc.AddField(document.NewTextFieldWithIndexingOptions("title", []byte("mister"), document.INDEX_FIELD|document.STORE_FIELD))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
fieldName1 := idx.fieldIndexToName(1)
if fieldName1 != "name" {
t.Errorf("expected field named 'name', got '%s'", fieldName1)
}
fieldName2 := idx.fieldIndexToName(2)
if fieldName2 != "title" {
t.Errorf("expected field named 'title', got '%s'", fieldName2)
}
fieldName3 := idx.fieldIndexToName(3)
if fieldName3 != "" {
t.Errorf("expected field named '', got '%s'", fieldName3)
}
}
func TestIndexTermReaderCompositeFields(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
if err != nil {
t.Error(err)
}
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
doc := document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("test"), document.INDEX_FIELD|document.STORE_FIELD|document.INCLUDE_TERM_VECTORS))
doc.AddField(document.NewTextFieldWithIndexingOptions("title", []byte("mister"), document.INDEX_FIELD|document.STORE_FIELD|document.INCLUDE_TERM_VECTORS))
doc.AddField(document.NewCompositeFieldWithIndexingOptions("_all", true, nil, nil, document.INDEX_FIELD|document.INCLUDE_TERM_VECTORS))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
termFieldReader, err := idx.TermFieldReader([]byte("mister"), "_all")
if err != nil {
t.Error(err)
}
tfd, err := termFieldReader.Next()
for tfd != nil && err == nil {
if tfd.ID != "1" {
t.Errorf("expected to find document id 1")
}
tfd, err = termFieldReader.Next()
}
if err != nil {
t.Error(err)
}
}
func TestIndexDocumentFieldTerms(t *testing.T) {
defer os.RemoveAll("test")
store, err := leveldb.Open("test", true)
if err != nil {
t.Error(err)
}
idx := NewUpsideDownCouch(store)
err = idx.Open()
if err != nil {
t.Errorf("error opening index: %v", err)
}
defer idx.Close()
doc := document.NewDocument("1")
doc.AddField(document.NewTextFieldWithIndexingOptions("name", []byte("test"), document.INDEX_FIELD|document.STORE_FIELD|document.INCLUDE_TERM_VECTORS))
doc.AddField(document.NewTextFieldWithIndexingOptions("title", []byte("mister"), document.INDEX_FIELD|document.STORE_FIELD|document.INCLUDE_TERM_VECTORS))
doc.AddField(document.NewCompositeFieldWithIndexingOptions("_all", true, nil, nil, document.INDEX_FIELD|document.INCLUDE_TERM_VECTORS))
err = idx.Update(doc)
if err != nil {
t.Errorf("Error updating index: %v", err)
}
fieldTerms, err := idx.DocumentFieldTerms("1")
if err != nil {
t.Error(err)
}
expectedFieldTerms := index.FieldTerms{
"name": []string{"test"},
"title": []string{"mister"},
"_all": []string{"test", "mister"},
}
if !reflect.DeepEqual(fieldTerms, expectedFieldTerms) {
t.Errorf("expected field terms: %#v, got: %#v", expectedFieldTerms, fieldTerms)
}
}