From 0c48a9e6c298e3699667c0ce9e1af2398ea9f142 Mon Sep 17 00:00:00 2001 From: Abhi Dangeti Date: Wed, 5 Apr 2023 08:22:40 -0600 Subject: [PATCH] Inheriting the correct analyzer when default mapping is in use (#1807) Here's an unhandled situation: - Say one defines a default dynamic mapping with a non-standard analyzer - Field content is indexed correctly per this non-standard analyzer - But, now let them run an analytic query over a field (that exists) - - This analytic query is incorrectly pulling the definition from the index's default_analyzer (`standard`) as opposed to the non-standard analyzer. This situation is not handled properly only for the default mapping and not type mappings. Also, https://issues.couchbase.com/browse/MB-56306 --- mapping/index.go | 12 +++++++++++- search_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mapping/index.go b/mapping/index.go index 1d982dd41..ee90aafcb 100644 --- a/mapping/index.go +++ b/mapping/index.go @@ -364,6 +364,7 @@ func (im *IndexMappingImpl) AnalyzerNameForPath(path string) string { return analyzerName } } + // now try the default mapping pathMapping := im.DefaultMapping.documentMappingForPath(path) if pathMapping != nil { @@ -377,7 +378,16 @@ func (im *IndexMappingImpl) AnalyzerNameForPath(path string) string { // next we will try default analyzers for the path pathDecoded := decodePath(path) for _, docMapping := range im.TypeMapping { - rv := docMapping.defaultAnalyzerName(pathDecoded) + if docMapping.Enabled { + rv := docMapping.defaultAnalyzerName(pathDecoded) + if rv != "" { + return rv + } + } + } + // now the default analyzer for the default mapping + if im.DefaultMapping.Enabled { + rv := im.DefaultMapping.defaultAnalyzerName(pathDecoded) if rv != "" { return rv } diff --git a/search_test.go b/search_test.go index 546cdefe7..a3191f8f3 100644 --- a/search_test.go +++ b/search_test.go @@ -2113,3 +2113,44 @@ func TestGeoShapePolygonContainsPoint(t *testing.T) { } } } + +func TestAnalyzerInheritanceForDefaultDynamicMapping(t *testing.T) { + tmpIndexPath := createTmpIndexPath(t) + defer cleanupTmpIndexPath(t, tmpIndexPath) + + imap := mapping.NewIndexMapping() + imap.DefaultMapping.DefaultAnalyzer = keyword.Name + + idx, err := New(tmpIndexPath, imap) + if err != nil { + t.Fatal(err) + } + defer func() { + err = idx.Close() + if err != nil { + t.Fatal(err) + } + }() + + doc := map[string]interface{}{ + "fieldX": "AbCdEf", + } + + if err = idx.Index("doc", doc); err != nil { + t.Fatal(err) + } + + // Match query to apply keyword analyzer to fieldX. + mq := NewMatchQuery("AbCdEf") + mq.SetField("fieldX") + + sr := NewSearchRequest(mq) + results, err := idx.Search(sr) + if err != nil { + t.Fatal(err) + } + + if len(results.Hits) != 1 { + t.Fatalf("expected 1 hit, got %d", len(results.Hits)) + } +}