Some checks failed
Coverage / coverage (push) Failing after 6s
Tests / test (1.24.x, ubuntu-latest) (push) Failing after 42s
Tests / test (1.26.x, ubuntu-latest) (push) Failing after 38s
Tests / test (1.25.x, ubuntu-latest) (push) Failing after 35s
Tests / test (1.25.x, windows-latest) (push) Has been cancelled
Tests / test (1.26.x, macos-latest) (push) Has been cancelled
Tests / test (1.26.x, windows-latest) (push) Has been cancelled
Tests / test (1.24.x, macos-latest) (push) Has been cancelled
Tests / test (1.24.x, windows-latest) (push) Has been cancelled
Tests / test (1.25.x, macos-latest) (push) Has been cancelled
3251 lines
86 KiB
Go
3251 lines
86 KiB
Go
// Copyright (c) 2025 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 (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/rand"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/blevesearch/bleve/v2/analysis/analyzer/custom"
|
|
"github.com/blevesearch/bleve/v2/analysis/analyzer/simple"
|
|
"github.com/blevesearch/bleve/v2/analysis/analyzer/standard"
|
|
"github.com/blevesearch/bleve/v2/analysis/datetime/percent"
|
|
"github.com/blevesearch/bleve/v2/analysis/datetime/sanitized"
|
|
"github.com/blevesearch/bleve/v2/analysis/lang/en"
|
|
"github.com/blevesearch/bleve/v2/analysis/token/lowercase"
|
|
"github.com/blevesearch/bleve/v2/analysis/tokenizer/letter"
|
|
"github.com/blevesearch/bleve/v2/analysis/tokenizer/whitespace"
|
|
"github.com/blevesearch/bleve/v2/index/scorch"
|
|
"github.com/blevesearch/bleve/v2/index/scorch/mergeplan"
|
|
"github.com/blevesearch/bleve/v2/mapping"
|
|
index "github.com/blevesearch/bleve_index_api"
|
|
)
|
|
|
|
func TestCompareFieldMapping(t *testing.T) {
|
|
tests := []struct {
|
|
original *mapping.FieldMapping
|
|
updated *mapping.FieldMapping
|
|
indexFieldInfo *index.UpdateFieldInfo
|
|
err bool
|
|
}{
|
|
{ // both nil => error
|
|
original: nil,
|
|
updated: nil,
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // updated nil => delete all
|
|
original: &mapping.FieldMapping{},
|
|
updated: nil,
|
|
indexFieldInfo: &index.UpdateFieldInfo{
|
|
Deleted: true,
|
|
},
|
|
err: false,
|
|
},
|
|
{ // type changed => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "text",
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "datetime",
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // synonym source changed for text => updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "text",
|
|
SynonymSource: "a",
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "text",
|
|
SynonymSource: "b",
|
|
},
|
|
indexFieldInfo: &index.UpdateFieldInfo{},
|
|
err: false,
|
|
},
|
|
{ // analyser changed for text => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "text",
|
|
Analyzer: "a",
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "text",
|
|
Analyzer: "b",
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // dims changed for vector => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "vector",
|
|
Dims: 128,
|
|
Similarity: "l2_norm",
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "vector",
|
|
Dims: 1024,
|
|
Similarity: "l2_norm",
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // similarity changed for vectorbase64 => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "vector_base64",
|
|
Similarity: "l2_norm",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "vector_base64",
|
|
Similarity: "dot_product",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // vectorindexoptimizedfor chagned for vector => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "vector",
|
|
Similarity: "dot_product",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "vector",
|
|
Similarity: "dot_product",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "latency",
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // gpu changed for vector => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "vector",
|
|
Similarity: "dot_product",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
GPU: false,
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "vector",
|
|
Similarity: "dot_product",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
GPU: true,
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // gpu changed for vectorbase64 => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "vector_base64",
|
|
Similarity: "dot_product",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
GPU: false,
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "vector_base64",
|
|
Similarity: "dot_product",
|
|
Dims: 128,
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
GPU: true,
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // includeinall changed => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
IncludeInAll: true,
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
IncludeInAll: false,
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ //includetermvectors changed => not updatable
|
|
original: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
IncludeTermVectors: false,
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
IncludeTermVectors: true,
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // store changed after all checks => updatable with store delete
|
|
original: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
SkipFreqNorm: true,
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
SkipFreqNorm: false,
|
|
},
|
|
indexFieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{ // index changed after all checks => updatable with index and docvalues delete
|
|
original: &mapping.FieldMapping{
|
|
Type: "geopoint",
|
|
Index: true,
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "geopoint",
|
|
Index: false,
|
|
},
|
|
indexFieldInfo: &index.UpdateFieldInfo{
|
|
Index: true,
|
|
DocValues: true,
|
|
},
|
|
err: false,
|
|
},
|
|
{ // docvalues changed after all checks => docvalues delete
|
|
original: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
DocValues: true,
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Type: "numeric",
|
|
DocValues: false,
|
|
},
|
|
indexFieldInfo: &index.UpdateFieldInfo{
|
|
DocValues: true,
|
|
},
|
|
err: false,
|
|
},
|
|
{ // no relavent changes => continue but no op
|
|
original: &mapping.FieldMapping{
|
|
Name: "",
|
|
Type: "datetime",
|
|
Analyzer: "a",
|
|
Store: true,
|
|
Index: false,
|
|
IncludeTermVectors: true,
|
|
IncludeInAll: false,
|
|
DateFormat: "a",
|
|
DocValues: false,
|
|
SkipFreqNorm: true,
|
|
Dims: 128,
|
|
Similarity: "dot_product",
|
|
VectorIndexOptimizedFor: "memory-efficient",
|
|
SynonymSource: "a",
|
|
},
|
|
updated: &mapping.FieldMapping{
|
|
Name: "",
|
|
Type: "datetime",
|
|
Analyzer: "b",
|
|
Store: true,
|
|
Index: false,
|
|
IncludeTermVectors: true,
|
|
IncludeInAll: false,
|
|
DateFormat: "a",
|
|
DocValues: false,
|
|
SkipFreqNorm: true,
|
|
Dims: 256,
|
|
Similarity: "l2_norm",
|
|
VectorIndexOptimizedFor: "latency",
|
|
SynonymSource: "b",
|
|
},
|
|
indexFieldInfo: &index.UpdateFieldInfo{},
|
|
err: false,
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
rv, err := compareFieldMapping(test.original, test.updated)
|
|
|
|
if err == nil && test.err || err != nil && !test.err {
|
|
t.Errorf("Unexpected error value for test %d, expecting %t, got %v\n", i, test.err, err)
|
|
}
|
|
if rv == nil && test.indexFieldInfo != nil || rv != nil && test.indexFieldInfo == nil || !reflect.DeepEqual(rv, test.indexFieldInfo) {
|
|
t.Errorf("Unexpected index field info value for test %d, expecting %+v, got %+v, err %v", i, test.indexFieldInfo, rv, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCompareMappings(t *testing.T) {
|
|
tests := []struct {
|
|
original *mapping.IndexMappingImpl
|
|
updated *mapping.IndexMappingImpl
|
|
err bool
|
|
}{
|
|
{ // changed type field when non empty mappings are present => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeField: "a",
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"a": {},
|
|
"b": {},
|
|
},
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeField: "b",
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"a": {},
|
|
"b": {},
|
|
},
|
|
},
|
|
err: true,
|
|
},
|
|
{ // changed default type => error
|
|
original: &mapping.IndexMappingImpl{
|
|
DefaultType: "a",
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
DefaultType: "b",
|
|
},
|
|
err: true,
|
|
},
|
|
{ // changed default analyzer => analyser true
|
|
original: &mapping.IndexMappingImpl{
|
|
DefaultAnalyzer: "a",
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
DefaultAnalyzer: "b",
|
|
},
|
|
err: false,
|
|
},
|
|
{ // changed default datetimeparser => datetimeparser true
|
|
original: &mapping.IndexMappingImpl{
|
|
DefaultDateTimeParser: "a",
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
DefaultDateTimeParser: "b",
|
|
},
|
|
err: false,
|
|
},
|
|
{ // changed default synonym source => synonym source true
|
|
original: &mapping.IndexMappingImpl{
|
|
DefaultSynonymSource: "a",
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
DefaultSynonymSource: "b",
|
|
},
|
|
err: false,
|
|
},
|
|
{ // changed default field => false
|
|
original: &mapping.IndexMappingImpl{
|
|
DefaultField: "a",
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
DefaultField: "b",
|
|
},
|
|
err: false,
|
|
},
|
|
{ // changed index dynamic => error
|
|
original: &mapping.IndexMappingImpl{
|
|
IndexDynamic: true,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
IndexDynamic: false,
|
|
},
|
|
err: true,
|
|
},
|
|
{ // changed store dynamic => error
|
|
original: &mapping.IndexMappingImpl{
|
|
StoreDynamic: false,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
StoreDynamic: true,
|
|
},
|
|
err: true,
|
|
},
|
|
{ // changed docvalues dynamic => error
|
|
original: &mapping.IndexMappingImpl{
|
|
DocValuesDynamic: true,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
DocValuesDynamic: false,
|
|
},
|
|
err: true,
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
err := compareMappings(test.original, test.updated)
|
|
|
|
if err == nil && test.err || err != nil && !test.err {
|
|
t.Errorf("Unexpected error value for test %d, expecting %t, got %v\n", i, test.err, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCompareAnalysers(t *testing.T) {
|
|
|
|
ori := mapping.NewIndexMapping()
|
|
ori.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
ori.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
ori.DefaultMapping.AddFieldMappingsAt("c", NewTextFieldMapping())
|
|
ori.DefaultMapping.Properties["b"].DefaultAnalyzer = "3xbla"
|
|
ori.DefaultMapping.Properties["c"].DefaultAnalyzer = simple.Name
|
|
|
|
upd := mapping.NewIndexMapping()
|
|
upd.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
upd.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
upd.DefaultMapping.AddFieldMappingsAt("c", NewTextFieldMapping())
|
|
upd.DefaultMapping.Properties["b"].DefaultAnalyzer = "3xbla"
|
|
upd.DefaultMapping.Properties["c"].DefaultAnalyzer = simple.Name
|
|
|
|
if err := ori.AddCustomAnalyzer("3xbla", map[string]interface{}{
|
|
"type": custom.Name,
|
|
"tokenizer": whitespace.Name,
|
|
"token_filters": []interface{}{lowercase.Name, "stop_en"},
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := upd.AddCustomAnalyzer("3xbla", map[string]interface{}{
|
|
"type": custom.Name,
|
|
"tokenizer": whitespace.Name,
|
|
"token_filters": []interface{}{lowercase.Name, "stop_en"},
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
oriPaths := map[string]*pathInfo{
|
|
"a": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "text",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "a",
|
|
parentPath: "",
|
|
},
|
|
"b": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "text",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "b",
|
|
parentPath: "",
|
|
},
|
|
"c": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "text",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "c",
|
|
parentPath: "",
|
|
},
|
|
}
|
|
|
|
updPaths := map[string]*pathInfo{
|
|
"a": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "text",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "a",
|
|
parentPath: "",
|
|
},
|
|
"b": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "text",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "b",
|
|
parentPath: "",
|
|
},
|
|
"c": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "text",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "c",
|
|
parentPath: "",
|
|
},
|
|
}
|
|
|
|
// Test case has identical analysers for text fields
|
|
err := compareAnalysers(oriPaths, updPaths, ori, upd)
|
|
if err != nil {
|
|
t.Errorf("Expected error to be nil, got %v", err)
|
|
}
|
|
|
|
ori2 := mapping.NewIndexMapping()
|
|
ori2.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
ori2.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
ori2.DefaultMapping.AddFieldMappingsAt("c", NewTextFieldMapping())
|
|
ori2.DefaultMapping.Properties["b"].DefaultAnalyzer = "3xbla"
|
|
ori2.DefaultMapping.Properties["c"].DefaultAnalyzer = simple.Name
|
|
|
|
upd2 := mapping.NewIndexMapping()
|
|
upd2.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
upd2.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
upd2.DefaultMapping.AddFieldMappingsAt("c", NewTextFieldMapping())
|
|
upd2.DefaultMapping.Properties["b"].DefaultAnalyzer = "3xbla"
|
|
upd2.DefaultMapping.Properties["c"].DefaultAnalyzer = simple.Name
|
|
|
|
if err := ori2.AddCustomAnalyzer("3xbla", map[string]interface{}{
|
|
"type": custom.Name,
|
|
"tokenizer": whitespace.Name,
|
|
"token_filters": []interface{}{lowercase.Name, "stop_en"},
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := upd2.AddCustomAnalyzer("3xbla", map[string]interface{}{
|
|
"type": custom.Name,
|
|
"tokenizer": letter.Name,
|
|
"token_filters": []interface{}{lowercase.Name, "stop_en"},
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Test case has different custom analyser for field "b"
|
|
err = compareAnalysers(oriPaths, updPaths, ori2, upd2)
|
|
if err == nil {
|
|
t.Errorf("Expected error, got nil")
|
|
}
|
|
}
|
|
|
|
func TestCompareDatetimeParsers(t *testing.T) {
|
|
|
|
ori := mapping.NewIndexMapping()
|
|
ori.DefaultMapping.AddFieldMappingsAt("a", NewDateTimeFieldMapping())
|
|
ori.DefaultMapping.AddFieldMappingsAt("b", NewDateTimeFieldMapping())
|
|
ori.DefaultMapping.AddFieldMappingsAt("c", NewDateTimeFieldMapping())
|
|
ori.DefaultMapping.Properties["b"].Fields[0].DateFormat = "customDT"
|
|
ori.DefaultMapping.Properties["c"].Fields[0].DateFormat = percent.Name
|
|
|
|
upd := mapping.NewIndexMapping()
|
|
upd.DefaultMapping.AddFieldMappingsAt("a", NewDateTimeFieldMapping())
|
|
upd.DefaultMapping.AddFieldMappingsAt("b", NewDateTimeFieldMapping())
|
|
upd.DefaultMapping.AddFieldMappingsAt("c", NewDateTimeFieldMapping())
|
|
upd.DefaultMapping.Properties["b"].Fields[0].DateFormat = "customDT"
|
|
upd.DefaultMapping.Properties["c"].Fields[0].DateFormat = percent.Name
|
|
|
|
err := ori.AddCustomDateTimeParser("customDT", map[string]interface{}{
|
|
"type": sanitized.Name,
|
|
"layouts": []interface{}{
|
|
"02/01/2006 15:04:05",
|
|
"2006/01/02 3:04PM",
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = upd.AddCustomDateTimeParser("customDT", map[string]interface{}{
|
|
"type": sanitized.Name,
|
|
"layouts": []interface{}{
|
|
"02/01/2006 15:04:05",
|
|
"2006/01/02 3:04PM",
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
oriPaths := map[string]*pathInfo{
|
|
"a": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "datetime",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "a",
|
|
parentPath: "",
|
|
},
|
|
"b": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "datetime",
|
|
DateFormat: "customDT",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "b",
|
|
parentPath: "",
|
|
},
|
|
"c": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "datetime",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "c",
|
|
parentPath: "",
|
|
},
|
|
}
|
|
|
|
updPaths := map[string]*pathInfo{
|
|
"a": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "datetime",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "a",
|
|
parentPath: "",
|
|
},
|
|
"b": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "datetime",
|
|
DateFormat: "customDT",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "b",
|
|
parentPath: "",
|
|
},
|
|
"c": {
|
|
fieldMapInfo: []*fieldMapInfo{
|
|
{
|
|
fieldMapping: &mapping.FieldMapping{
|
|
Type: "datetime",
|
|
},
|
|
},
|
|
},
|
|
dynamic: false,
|
|
path: "c",
|
|
parentPath: "",
|
|
},
|
|
}
|
|
|
|
// Test case has identical datetime parsers for all fields
|
|
err = compareDateTimeParsers(oriPaths, updPaths, ori, upd)
|
|
if err != nil {
|
|
t.Fatalf("Expected error to be nil, got %v", err)
|
|
}
|
|
|
|
ori2 := mapping.NewIndexMapping()
|
|
ori2.DefaultMapping.AddFieldMappingsAt("a", NewDateTimeFieldMapping())
|
|
ori2.DefaultMapping.AddFieldMappingsAt("b", NewDateTimeFieldMapping())
|
|
ori2.DefaultMapping.AddFieldMappingsAt("c", NewDateTimeFieldMapping())
|
|
ori2.DefaultMapping.Properties["b"].Fields[0].DateFormat = "customDT"
|
|
ori2.DefaultMapping.Properties["c"].Fields[0].DateFormat = percent.Name
|
|
|
|
upd2 := mapping.NewIndexMapping()
|
|
upd2.DefaultMapping.AddFieldMappingsAt("a", NewDateTimeFieldMapping())
|
|
upd2.DefaultMapping.AddFieldMappingsAt("b", NewDateTimeFieldMapping())
|
|
upd2.DefaultMapping.AddFieldMappingsAt("c", NewDateTimeFieldMapping())
|
|
upd2.DefaultMapping.Properties["b"].Fields[0].DateFormat = "customDT"
|
|
upd2.DefaultMapping.Properties["c"].Fields[0].DateFormat = percent.Name
|
|
|
|
err = ori2.AddCustomDateTimeParser("customDT", map[string]interface{}{
|
|
"type": sanitized.Name,
|
|
"layouts": []interface{}{
|
|
"02/01/2006 15:04:05",
|
|
"2006/01/02 3:04PM",
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = upd2.AddCustomDateTimeParser("customDT", map[string]interface{}{
|
|
"type": sanitized.Name,
|
|
"layouts": []interface{}{
|
|
"02/01/2006 15:04:05",
|
|
"2006/01/02",
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// test case has different custom datetime parser for field "b"
|
|
err = compareDateTimeParsers(oriPaths, updPaths, ori2, upd2)
|
|
if err == nil {
|
|
t.Errorf("Expected error, got nil")
|
|
}
|
|
}
|
|
|
|
func TestCompareSynonymSources(t *testing.T) {
|
|
|
|
ori := mapping.NewIndexMapping()
|
|
ori.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
ori.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
ori.DefaultMapping.DefaultSynonymSource = "syn1"
|
|
ori.DefaultMapping.Properties["b"].Fields[0].SynonymSource = "syn2"
|
|
|
|
upd := mapping.NewIndexMapping()
|
|
upd.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
upd.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
upd.DefaultMapping.DefaultSynonymSource = "syn1"
|
|
upd.DefaultMapping.Properties["b"].Fields[0].SynonymSource = "syn2"
|
|
|
|
err := ori.AddSynonymSource("syn1", map[string]interface{}{
|
|
"collection": "col1",
|
|
"analyzer": simple.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = ori.AddSynonymSource("syn2", map[string]interface{}{
|
|
"collection": "col2",
|
|
"analyzer": standard.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = upd.AddSynonymSource("syn1", map[string]interface{}{
|
|
"collection": "col1",
|
|
"analyzer": simple.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = upd.AddSynonymSource("syn2", map[string]interface{}{
|
|
"collection": "col2",
|
|
"analyzer": standard.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Test case has identical synonym sources
|
|
err = compareSynonymSources(ori, upd)
|
|
if err != nil {
|
|
t.Errorf("Expected error to be nil, got %v", err)
|
|
}
|
|
|
|
ori2 := mapping.NewIndexMapping()
|
|
ori2.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
ori2.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
ori2.DefaultMapping.DefaultSynonymSource = "syn1"
|
|
ori2.DefaultMapping.Properties["b"].Fields[0].SynonymSource = "syn2"
|
|
|
|
upd2 := mapping.NewIndexMapping()
|
|
upd2.DefaultMapping.AddFieldMappingsAt("a", NewTextFieldMapping())
|
|
upd2.DefaultMapping.AddFieldMappingsAt("b", NewTextFieldMapping())
|
|
upd2.DefaultMapping.DefaultSynonymSource = "syn1"
|
|
upd2.DefaultMapping.Properties["b"].Fields[0].SynonymSource = "syn2"
|
|
|
|
err = ori2.AddSynonymSource("syn1", map[string]interface{}{
|
|
"collection": "col1",
|
|
"analyzer": simple.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = ori2.AddSynonymSource("syn2", map[string]interface{}{
|
|
"collection": "col2",
|
|
"analyzer": standard.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = upd2.AddSynonymSource("syn1", map[string]interface{}{
|
|
"collection": "col1",
|
|
"analyzer": simple.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = upd2.AddSynonymSource("syn2", map[string]interface{}{
|
|
"collection": "col3",
|
|
"analyzer": standard.Name,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// test case has different synonym sources
|
|
err = compareSynonymSources(ori2, upd2)
|
|
if err == nil {
|
|
t.Errorf("Expected error, got nil")
|
|
}
|
|
}
|
|
|
|
func TestDeletedFields(t *testing.T) {
|
|
tests := []struct {
|
|
original *mapping.IndexMappingImpl
|
|
updated *mapping.IndexMappingImpl
|
|
fieldInfo map[string]*index.UpdateFieldInfo
|
|
err bool
|
|
}{
|
|
{
|
|
// changed default analyzer with index dynamic
|
|
// => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{},
|
|
DefaultAnalyzer: standard.Name,
|
|
IndexDynamic: true,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{},
|
|
DefaultAnalyzer: simple.Name,
|
|
IndexDynamic: true,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{
|
|
// changed default analyzer within a mapping with index dynamic
|
|
// => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: true,
|
|
DefaultAnalyzer: standard.Name,
|
|
},
|
|
DefaultAnalyzer: "",
|
|
IndexDynamic: true,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: true,
|
|
DefaultAnalyzer: simple.Name,
|
|
},
|
|
IndexDynamic: true,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{
|
|
// changed default datetime parser with index dynamic
|
|
// => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{},
|
|
DefaultDateTimeParser: percent.Name,
|
|
IndexDynamic: true,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{},
|
|
DefaultDateTimeParser: sanitized.Name,
|
|
IndexDynamic: true,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{
|
|
// no change between original and updated having type and default mapping
|
|
// => empty fieldInfo with no error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: map[string]*index.UpdateFieldInfo{},
|
|
err: false,
|
|
},
|
|
{
|
|
// no changes in type mappings and default mapping disabled with changes
|
|
// => empty fieldInfo with no error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: false,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: false,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"d": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: map[string]*index.UpdateFieldInfo{},
|
|
err: false,
|
|
},
|
|
{
|
|
// new type mappings in updated => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{
|
|
// new mappings in default mapping => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{
|
|
// fully removed mapping in type with some dynamic => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: true,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{
|
|
// semi removed mapping in default with some dynamic
|
|
// proper fieldInfo with no errors
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: map[string]*index.UpdateFieldInfo{
|
|
"b": {
|
|
Index: true,
|
|
DocValues: true,
|
|
},
|
|
},
|
|
err: false,
|
|
},
|
|
{
|
|
// two fields from diff paths with removed content matching
|
|
// => relavent fieldInfo
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: map[string]*index.UpdateFieldInfo{
|
|
"a": {
|
|
Index: true,
|
|
DocValues: true,
|
|
},
|
|
},
|
|
err: false,
|
|
},
|
|
{
|
|
// two fields from diff paths with removed content not matching
|
|
// => error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: nil,
|
|
err: true,
|
|
},
|
|
{
|
|
// two fields from the same path => relavent fieldInfo
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Name: "a",
|
|
Type: "numeric",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
{
|
|
Name: "b",
|
|
Type: "numeric",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Name: "a",
|
|
Type: "numeric",
|
|
Index: false,
|
|
Store: true,
|
|
},
|
|
{
|
|
Name: "b",
|
|
Type: "numeric",
|
|
Index: true,
|
|
Store: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: map[string]*index.UpdateFieldInfo{
|
|
"a": {
|
|
Index: true,
|
|
DocValues: true,
|
|
},
|
|
"b": {
|
|
Store: true,
|
|
},
|
|
},
|
|
err: false,
|
|
},
|
|
{
|
|
// one store, one index, one dynamic and one all removed in type and default
|
|
// => relavent fieldInfo without error
|
|
original: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map3": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
DocValues: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"d": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: true,
|
|
Store: true,
|
|
DocValues: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
updated: &mapping.IndexMappingImpl{
|
|
TypeMapping: map[string]*mapping.DocumentMapping{
|
|
"map1": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Index: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map2": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
Store: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"map3": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "numeric",
|
|
DocValues: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
DefaultMapping: &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
IndexDynamic: false,
|
|
StoreDynamic: false,
|
|
DocValuesDynamic: false,
|
|
CustomAnalysis: NewIndexMapping().CustomAnalysis,
|
|
},
|
|
fieldInfo: map[string]*index.UpdateFieldInfo{
|
|
"a": {
|
|
Index: true,
|
|
DocValues: true,
|
|
},
|
|
"b": {
|
|
Store: true,
|
|
},
|
|
"c": {
|
|
DocValues: true,
|
|
},
|
|
"d": {
|
|
Deleted: true,
|
|
},
|
|
},
|
|
err: false,
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
info, err := DeletedFields(test.original, test.updated)
|
|
|
|
if err == nil && test.err || err != nil && !test.err {
|
|
t.Errorf("Unexpected error value for test %d, expecting %t, got %v\n", i, test.err, err)
|
|
}
|
|
if info == nil && test.fieldInfo != nil || info != nil && test.fieldInfo == nil || !reflect.DeepEqual(info, test.fieldInfo) {
|
|
t.Errorf("Unexpected default info value for test %d, expecting %+v, got %+v, err %v", i, test.fieldInfo, info, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIndexUpdateText(t *testing.T) {
|
|
tmpIndexPath := createTmpIndexPath(t)
|
|
defer cleanupTmpIndexPath(t, tmpIndexPath)
|
|
|
|
indexMappingBefore := mapping.NewIndexMapping()
|
|
indexMappingBefore.TypeMapping = map[string]*mapping.DocumentMapping{}
|
|
indexMappingBefore.DefaultMapping = &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"d": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
}
|
|
indexMappingBefore.IndexDynamic = false
|
|
indexMappingBefore.StoreDynamic = false
|
|
indexMappingBefore.DocValuesDynamic = false
|
|
|
|
index, err := New(tmpIndexPath, indexMappingBefore)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
doc1 := map[string]interface{}{"a": "xyz", "b": "abc", "c": "def", "d": "ghi"}
|
|
doc2 := map[string]interface{}{"a": "uvw", "b": "rst", "c": "klm", "d": "pqr"}
|
|
doc3 := map[string]interface{}{"a": "xyz", "b": "def", "c": "abc", "d": "mno"}
|
|
batch := index.NewBatch()
|
|
err = batch.Index("001", doc1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = batch.Index("002", doc2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = batch.Index("003", doc3)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = index.Batch(batch)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = index.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
indexMappingAfter := mapping.NewIndexMapping()
|
|
indexMappingAfter.TypeMapping = map[string]*mapping.DocumentMapping{}
|
|
indexMappingAfter.DefaultMapping = &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: false,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
}
|
|
indexMappingAfter.IndexDynamic = false
|
|
indexMappingAfter.StoreDynamic = false
|
|
indexMappingAfter.DocValuesDynamic = false
|
|
|
|
mappingString, err := json.Marshal(indexMappingAfter)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config := map[string]interface{}{
|
|
"updated_mapping": string(mappingString),
|
|
}
|
|
|
|
index, err = OpenUsing(tmpIndexPath, config)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
err := index.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
q1 := NewSearchRequest(NewQueryStringQuery("a:*"))
|
|
q1.Fields = append(q1.Fields, "a")
|
|
res1, err := index.Search(q1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res1.Hits) != 3 {
|
|
t.Errorf("Expected 3 hits, got %d\n", len(res1.Hits))
|
|
}
|
|
if len(res1.Hits[0].Fields) != 1 {
|
|
t.Errorf("Expected 1 field, got %d\n", len(res1.Hits[0].Fields))
|
|
}
|
|
q2 := NewSearchRequest(NewQueryStringQuery("b:*"))
|
|
q2.Fields = append(q2.Fields, "b")
|
|
res2, err := index.Search(q2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res2.Hits) != 0 {
|
|
t.Errorf("Expected 0 hits, got %d\n", len(res2.Hits))
|
|
}
|
|
q3 := NewSearchRequest(NewQueryStringQuery("c:*"))
|
|
q3.Fields = append(q3.Fields, "c")
|
|
res3, err := index.Search(q3)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res3.Hits) != 3 {
|
|
t.Errorf("Expected 3 hits, got %d\n", len(res3.Hits))
|
|
}
|
|
if len(res3.Hits[0].Fields) != 0 {
|
|
t.Errorf("Expected 0 fields, got %d\n", len(res3.Hits[0].Fields))
|
|
}
|
|
q4 := NewSearchRequest(NewQueryStringQuery("d:*"))
|
|
q4.Fields = append(q4.Fields, "d")
|
|
res4, err := index.Search(q4)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res4.Hits) != 0 {
|
|
t.Errorf("Expected 0 hits, got %d\n", len(res4.Hits))
|
|
}
|
|
}
|
|
|
|
func TestIndexUpdateSynonym(t *testing.T) {
|
|
tmpIndexPath := createTmpIndexPath(t)
|
|
defer cleanupTmpIndexPath(t, tmpIndexPath)
|
|
|
|
synonymCollection := "collection1"
|
|
synonymSourceName := "english"
|
|
analyzer := en.AnalyzerName
|
|
synonymSourceConfig := map[string]interface{}{
|
|
"collection": synonymCollection,
|
|
"analyzer": analyzer,
|
|
}
|
|
|
|
a := mapping.NewTextFieldMapping()
|
|
a.Analyzer = analyzer
|
|
a.SynonymSource = synonymSourceName
|
|
a.IncludeInAll = false
|
|
|
|
b := mapping.NewTextFieldMapping()
|
|
b.Analyzer = analyzer
|
|
b.SynonymSource = synonymSourceName
|
|
b.IncludeInAll = false
|
|
|
|
c := mapping.NewTextFieldMapping()
|
|
c.Analyzer = analyzer
|
|
c.SynonymSource = synonymSourceName
|
|
c.IncludeInAll = false
|
|
|
|
indexMappingBefore := mapping.NewIndexMapping()
|
|
indexMappingBefore.DefaultMapping.AddFieldMappingsAt("a", a)
|
|
indexMappingBefore.DefaultMapping.AddFieldMappingsAt("b", b)
|
|
indexMappingBefore.DefaultMapping.AddFieldMappingsAt("c", c)
|
|
err := indexMappingBefore.AddSynonymSource(synonymSourceName, synonymSourceConfig)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
indexMappingBefore.IndexDynamic = false
|
|
indexMappingBefore.StoreDynamic = false
|
|
indexMappingBefore.DocValuesDynamic = false
|
|
|
|
index, err := New(tmpIndexPath, indexMappingBefore)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
doc1 := map[string]interface{}{
|
|
"a": `The hardworking employee consistently strives to exceed expectations.
|
|
His industrious nature makes him a valuable asset to any team.
|
|
His conscientious attention to detail ensures that projects are completed efficiently and accurately.
|
|
He remains persistent even in the face of challenges.`,
|
|
"b": `The hardworking employee consistently strives to exceed expectations.
|
|
His industrious nature makes him a valuable asset to any team.
|
|
His conscientious attention to detail ensures that projects are completed efficiently and accurately.
|
|
He remains persistent even in the face of challenges.`,
|
|
"c": `The hardworking employee consistently strives to exceed expectations.
|
|
His industrious nature makes him a valuable asset to any team.
|
|
His conscientious attention to detail ensures that projects are completed efficiently and accurately.
|
|
He remains persistent even in the face of challenges.`,
|
|
}
|
|
doc2 := map[string]interface{}{
|
|
"a": `The tranquil surroundings of the retreat provide a perfect escape from the hustle and bustle of city life.
|
|
Guests enjoy the peaceful atmosphere, which is perfect for relaxation and rejuvenation.
|
|
The calm environment offers the ideal place to meditate and connect with nature.
|
|
Even the most stressed individuals find themselves feeling relaxed and at ease.`,
|
|
"b": `The tranquil surroundings of the retreat provide a perfect escape from the hustle and bustle of city life.
|
|
Guests enjoy the peaceful atmosphere, which is perfect for relaxation and rejuvenation.
|
|
The calm environment offers the ideal place to meditate and connect with nature.
|
|
Even the most stressed individuals find themselves feeling relaxed and at ease.`,
|
|
"c": `The tranquil surroundings of the retreat provide a perfect escape from the hustle and bustle of city life.
|
|
Guests enjoy the peaceful atmosphere, which is perfect for relaxation and rejuvenation.
|
|
The calm environment offers the ideal place to meditate and connect with nature.
|
|
Even the most stressed individuals find themselves feeling relaxed and at ease.`,
|
|
}
|
|
synDoc1 := &SynonymDefinition{Synonyms: []string{"hardworking", "industrious", "conscientious", "persistent", "focused", "devoted"}}
|
|
synDoc2 := &SynonymDefinition{Synonyms: []string{"tranquil", "peaceful", "calm", "relaxed", "unruffled"}}
|
|
|
|
batch := index.NewBatch()
|
|
err = batch.IndexSynonym("001", synonymCollection, synDoc1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = batch.IndexSynonym("002", synonymCollection, synDoc2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = batch.Index("003", doc1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = batch.Index("004", doc2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = index.Batch(batch)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = index.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
indexMappingAfter := mapping.NewIndexMapping()
|
|
indexMappingAfter.DefaultMapping.AddFieldMappingsAt("a", a)
|
|
b.Index = false
|
|
indexMappingAfter.DefaultMapping.AddFieldMappingsAt("b", b)
|
|
err = indexMappingAfter.AddSynonymSource(synonymSourceName, synonymSourceConfig)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
indexMappingAfter.IndexDynamic = false
|
|
indexMappingAfter.StoreDynamic = false
|
|
indexMappingAfter.DocValuesDynamic = false
|
|
|
|
mappingString, err := json.Marshal(indexMappingAfter)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
config := map[string]interface{}{
|
|
"updated_mapping": string(mappingString),
|
|
}
|
|
|
|
index, err = OpenUsing(tmpIndexPath, config)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
err := index.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
q1 := NewSearchRequest(NewQueryStringQuery("a:devoted"))
|
|
res1, err := index.Search(q1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res1.Hits) != 1 {
|
|
t.Errorf("Expected 1 hit, got %d\n", len(res1.Hits))
|
|
}
|
|
|
|
q2 := NewSearchRequest(NewQueryStringQuery("b:devoted"))
|
|
res2, err := index.Search(q2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res2.Hits) != 0 {
|
|
t.Errorf("Expected 0 hits, got %d\n", len(res2.Hits))
|
|
}
|
|
|
|
q3 := NewSearchRequest(NewQueryStringQuery("c:unruffled"))
|
|
res3, err := index.Search(q3)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res3.Hits) != 0 {
|
|
t.Errorf("Expected 0 hits, got %d\n", len(res3.Hits))
|
|
}
|
|
}
|
|
|
|
func TestIndexUpdateMerge(t *testing.T) {
|
|
tmpIndexPath := createTmpIndexPath(t)
|
|
defer cleanupTmpIndexPath(t, tmpIndexPath)
|
|
|
|
indexMappingBefore := mapping.NewIndexMapping()
|
|
indexMappingBefore.TypeMapping = map[string]*mapping.DocumentMapping{}
|
|
indexMappingBefore.DefaultMapping = &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"d": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
}
|
|
indexMappingBefore.IndexDynamic = false
|
|
indexMappingBefore.StoreDynamic = false
|
|
indexMappingBefore.DocValuesDynamic = false
|
|
|
|
index, err := New(tmpIndexPath, indexMappingBefore)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
numDocsPerBatch := 1000
|
|
numBatches := 10
|
|
|
|
var batch *Batch
|
|
doc := make(map[string]interface{})
|
|
const letters = "abcdefghijklmnopqrstuvwxyz"
|
|
|
|
randStr := func() string {
|
|
result := make([]byte, 3)
|
|
for i := 0; i < 3; i++ {
|
|
result[i] = letters[rand.Intn(len(letters))]
|
|
}
|
|
return string(result)
|
|
}
|
|
for i := 0; i < numBatches; i++ {
|
|
batch = index.NewBatch()
|
|
for j := 0; j < numDocsPerBatch; j++ {
|
|
doc["a"] = randStr()
|
|
doc["b"] = randStr()
|
|
doc["c"] = randStr()
|
|
doc["d"] = randStr()
|
|
err = batch.Index(fmt.Sprintf("%d", i*numDocsPerBatch+j), doc)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
err = index.Batch(batch)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
err = index.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
indexMappingAfter := mapping.NewIndexMapping()
|
|
indexMappingAfter.TypeMapping = map[string]*mapping.DocumentMapping{}
|
|
indexMappingAfter.DefaultMapping = &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"b": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: false,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
"c": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
}
|
|
indexMappingAfter.IndexDynamic = false
|
|
indexMappingAfter.StoreDynamic = false
|
|
indexMappingAfter.DocValuesDynamic = false
|
|
|
|
mappingString, err := json.Marshal(indexMappingAfter)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
config := map[string]interface{}{
|
|
"updated_mapping": string(mappingString),
|
|
}
|
|
|
|
index, err = OpenUsing(tmpIndexPath, config)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
err := index.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
impl, ok := index.(*indexImpl)
|
|
if !ok {
|
|
t.Fatalf("Typecasting index to indexImpl failed")
|
|
}
|
|
sindex, ok := impl.i.(*scorch.Scorch)
|
|
if !ok {
|
|
t.Fatalf("Typecasting index to scorch index failed")
|
|
}
|
|
|
|
err = sindex.ForceMerge(context.Background(), &mergeplan.SingleSegmentMergePlanOptions)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
q1 := NewSearchRequest(NewQueryStringQuery("a:*"))
|
|
q1.Fields = append(q1.Fields, "a")
|
|
|
|
res1, err := index.Search(q1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res1.Hits) != 10 {
|
|
t.Errorf("Expected 10 hits, got %d\n", len(res1.Hits))
|
|
}
|
|
if len(res1.Hits[0].Fields) != 1 {
|
|
t.Errorf("Expected 1 field, got %d\n", len(res1.Hits[0].Fields))
|
|
}
|
|
q2 := NewSearchRequest(NewQueryStringQuery("b:*"))
|
|
q2.Fields = append(q2.Fields, "b")
|
|
res2, err := index.Search(q2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res2.Hits) != 0 {
|
|
t.Errorf("Expected 0 hits, got %d\n", len(res2.Hits))
|
|
}
|
|
q3 := NewSearchRequest(NewQueryStringQuery("c:*"))
|
|
q3.Fields = append(q3.Fields, "c")
|
|
res3, err := index.Search(q3)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res3.Hits) != 10 {
|
|
t.Errorf("Expected 10 hits, got %d\n", len(res3.Hits))
|
|
}
|
|
if len(res3.Hits[0].Fields) != 0 {
|
|
t.Errorf("Expected 0 fields, got %d\n", len(res3.Hits[0].Fields))
|
|
}
|
|
q4 := NewSearchRequest(NewQueryStringQuery("d:*"))
|
|
q4.Fields = append(q4.Fields, "d")
|
|
res4, err := index.Search(q4)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(res4.Hits) != 0 {
|
|
t.Errorf("Expected 0 hits, got %d\n", len(res4.Hits))
|
|
}
|
|
}
|
|
|
|
func BenchmarkIndexUpdateText(b *testing.B) {
|
|
|
|
tmpIndexPath := createTmpIndexPath(b)
|
|
defer cleanupTmpIndexPath(b, tmpIndexPath)
|
|
|
|
indexMappingBefore := mapping.NewIndexMapping()
|
|
indexMappingBefore.TypeMapping = map[string]*mapping.DocumentMapping{}
|
|
indexMappingBefore.DefaultMapping = &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: true,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
}
|
|
indexMappingBefore.IndexDynamic = false
|
|
indexMappingBefore.StoreDynamic = false
|
|
indexMappingBefore.DocValuesDynamic = false
|
|
|
|
index, err := New(tmpIndexPath, indexMappingBefore)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
numDocsPerBatch := 1000
|
|
numBatches := 5
|
|
|
|
var batch *Batch
|
|
doc := make(map[string]interface{})
|
|
const letters = "abcdefghijklmnopqrstuvwxyz"
|
|
|
|
randStr := func() string {
|
|
result := make([]byte, 3)
|
|
for i := 0; i < 3; i++ {
|
|
result[i] = letters[rand.Intn(len(letters))]
|
|
}
|
|
return string(result)
|
|
}
|
|
for i := 0; i < numBatches; i++ {
|
|
batch = index.NewBatch()
|
|
for j := 0; j < numDocsPerBatch; j++ {
|
|
doc["a"] = randStr()
|
|
err = batch.Index(fmt.Sprintf("%d", i*numDocsPerBatch+j), doc)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
err = index.Batch(batch)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
|
|
err = index.Close()
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
indexMappingAfter := mapping.NewIndexMapping()
|
|
indexMappingAfter.TypeMapping = map[string]*mapping.DocumentMapping{}
|
|
indexMappingAfter.DefaultMapping = &mapping.DocumentMapping{
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{
|
|
"a": {
|
|
Enabled: true,
|
|
Dynamic: false,
|
|
Properties: map[string]*mapping.DocumentMapping{},
|
|
Fields: []*mapping.FieldMapping{
|
|
{
|
|
Type: "text",
|
|
Index: true,
|
|
Store: false,
|
|
},
|
|
},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
},
|
|
},
|
|
Fields: []*mapping.FieldMapping{},
|
|
DefaultAnalyzer: "standard",
|
|
DefaultSynonymSource: "",
|
|
}
|
|
indexMappingAfter.IndexDynamic = false
|
|
indexMappingAfter.StoreDynamic = false
|
|
indexMappingAfter.DocValuesDynamic = false
|
|
|
|
mappingString, err := json.Marshal(indexMappingAfter)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
config := map[string]interface{}{
|
|
"updated_mapping": string(mappingString),
|
|
}
|
|
|
|
index, err = OpenUsing(tmpIndexPath, config)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer func() {
|
|
err := index.Close()
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
q := NewQueryStringQuery("a:*")
|
|
req := NewSearchRequest(q)
|
|
if _, err = index.Search(req); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIndexUpdateNestedMapping(t *testing.T) {
|
|
// Helper: create a mapping with optional nested structure
|
|
createCompanyMapping := func(nestedEmployees, nestedDepartments, nestedProjects, nestedLocations bool) *mapping.IndexMappingImpl {
|
|
rv := mapping.NewIndexMapping()
|
|
companyMapping := mapping.NewDocumentMapping()
|
|
|
|
// Basic fields
|
|
companyMapping.AddFieldMappingsAt("id", mapping.NewTextFieldMapping())
|
|
companyMapping.AddFieldMappingsAt("name", mapping.NewTextFieldMapping())
|
|
|
|
var deptMapping *mapping.DocumentMapping
|
|
// Departments nested conditionally
|
|
if !nestedDepartments {
|
|
deptMapping = mapping.NewDocumentMapping()
|
|
} else {
|
|
deptMapping = mapping.NewNestedDocumentMapping()
|
|
}
|
|
deptMapping.AddFieldMappingsAt("name", mapping.NewTextFieldMapping())
|
|
deptMapping.AddFieldMappingsAt("budget", mapping.NewNumericFieldMapping())
|
|
|
|
// Employees nested conditionally
|
|
var empMapping *mapping.DocumentMapping
|
|
if !nestedEmployees {
|
|
empMapping = mapping.NewNestedDocumentMapping()
|
|
} else {
|
|
empMapping = mapping.NewDocumentMapping()
|
|
}
|
|
empMapping.AddFieldMappingsAt("name", mapping.NewTextFieldMapping())
|
|
empMapping.AddFieldMappingsAt("role", mapping.NewTextFieldMapping())
|
|
deptMapping.AddSubDocumentMapping("employees", empMapping)
|
|
|
|
// Projects nested conditionally
|
|
var projMapping *mapping.DocumentMapping
|
|
if !nestedProjects {
|
|
projMapping = mapping.NewNestedDocumentMapping()
|
|
} else {
|
|
projMapping = mapping.NewDocumentMapping()
|
|
}
|
|
projMapping.AddFieldMappingsAt("title", mapping.NewTextFieldMapping())
|
|
projMapping.AddFieldMappingsAt("status", mapping.NewTextFieldMapping())
|
|
deptMapping.AddSubDocumentMapping("projects", projMapping)
|
|
|
|
companyMapping.AddSubDocumentMapping("departments", deptMapping)
|
|
|
|
// Locations nested conditionally
|
|
var locMapping *mapping.DocumentMapping
|
|
if nestedLocations {
|
|
locMapping = mapping.NewNestedDocumentMapping()
|
|
} else {
|
|
locMapping = mapping.NewDocumentMapping()
|
|
}
|
|
locMapping.AddFieldMappingsAt("address", mapping.NewTextFieldMapping())
|
|
locMapping.AddFieldMappingsAt("city", mapping.NewTextFieldMapping())
|
|
|
|
companyMapping.AddSubDocumentMapping("locations", locMapping)
|
|
|
|
rv.DefaultMapping.AddSubDocumentMapping("company", companyMapping)
|
|
return rv
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
original *mapping.IndexMappingImpl
|
|
updated *mapping.IndexMappingImpl
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "No nested to all nested",
|
|
original: createCompanyMapping(false, false, false, false),
|
|
updated: createCompanyMapping(true, true, true, true),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "No nested to mixed nested",
|
|
original: createCompanyMapping(false, false, false, false),
|
|
updated: createCompanyMapping(true, false, true, false),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "No nested to mixed nested",
|
|
original: createCompanyMapping(false, false, false, false),
|
|
updated: createCompanyMapping(true, true, true, false),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "Mixed nested to no nested",
|
|
original: createCompanyMapping(false, true, false, true),
|
|
updated: createCompanyMapping(false, false, true, true),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "All nested to no nested",
|
|
original: createCompanyMapping(true, true, true, true),
|
|
updated: createCompanyMapping(false, false, false, false),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "Mixed nested to all nested",
|
|
original: createCompanyMapping(true, false, true, false),
|
|
updated: createCompanyMapping(true, true, true, true),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "All nested to mixed nested",
|
|
original: createCompanyMapping(true, true, true, true),
|
|
updated: createCompanyMapping(true, false, true, false),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "No nested to no nested",
|
|
original: createCompanyMapping(false, false, false, false),
|
|
updated: createCompanyMapping(false, false, false, false),
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "All nested to all nested",
|
|
original: createCompanyMapping(true, true, true, true),
|
|
updated: createCompanyMapping(true, true, true, true),
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
_, err := DeletedFields(test.original, test.updated)
|
|
if (err != nil) != test.expectErr {
|
|
t.Errorf("Test '%s' unexpected error state: got %v, expectErr %t", test.name, err, test.expectErr)
|
|
}
|
|
}
|
|
}
|