-
Notifications
You must be signed in to change notification settings - Fork 688
/
pre_search.go
137 lines (121 loc) · 4.33 KB
/
pre_search.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (c) 2024 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 (
"github.com/blevesearch/bleve/v2/search"
)
// A preSearchResultProcessor processes the data in
// the preSearch result from multiple
// indexes in an alias and merges them together to
// create the final preSearch result
type preSearchResultProcessor interface {
// adds the preSearch result to the processor
add(*SearchResult, string)
// updates the final search result with the finalized
// data from the processor
finalize(*SearchResult)
}
// -----------------------------------------------------------------------------
// KNN preSearchResultProcessor for handling KNN presearch results
type knnPreSearchResultProcessor struct {
addFn func(sr *SearchResult, indexName string)
finalizeFn func(sr *SearchResult)
}
func (k *knnPreSearchResultProcessor) add(sr *SearchResult, indexName string) {
if k.addFn != nil {
k.addFn(sr, indexName)
}
}
func (k *knnPreSearchResultProcessor) finalize(sr *SearchResult) {
if k.finalizeFn != nil {
k.finalizeFn(sr)
}
}
// -----------------------------------------------------------------------------
// Synonym preSearchResultProcessor for handling Synonym presearch results
type synonymPreSearchResultProcessor struct {
finalizedFts search.FieldTermSynonymMap
}
func newSynonymPreSearchResultProcessor() *synonymPreSearchResultProcessor {
return &synonymPreSearchResultProcessor{}
}
func (s *synonymPreSearchResultProcessor) add(sr *SearchResult, indexName string) {
// Check if SynonymResult or the synonym data key is nil
if sr.SynonymResult == nil {
return
}
// Attempt to cast PreSearchResults to FieldTermSynonymMap
// Merge with finalizedFts or initialize it if nil
if s.finalizedFts == nil {
s.finalizedFts = sr.SynonymResult
} else {
s.finalizedFts.MergeWith(sr.SynonymResult)
}
}
func (s *synonymPreSearchResultProcessor) finalize(sr *SearchResult) {
// Set the finalized synonym data to the PreSearchResults
if s.finalizedFts != nil {
sr.SynonymResult = s.finalizedFts
}
}
// -----------------------------------------------------------------------------
// Master struct that can hold any number of presearch result processors
type compositePreSearchResultProcessor struct {
presearchResultProcessors []preSearchResultProcessor
}
// Implements the add method, which forwards to all the internal processors
func (m *compositePreSearchResultProcessor) add(sr *SearchResult, indexName string) {
for _, p := range m.presearchResultProcessors {
p.add(sr, indexName)
}
}
// Implements the finalize method, which forwards to all the internal processors
func (m *compositePreSearchResultProcessor) finalize(sr *SearchResult) {
for _, p := range m.presearchResultProcessors {
p.finalize(sr)
}
}
// -----------------------------------------------------------------------------
// Function to create the appropriate preSearchResultProcessor(s)
func createPreSearchResultProcessor(req *SearchRequest, flags *preSearchFlags) preSearchResultProcessor {
// return nil for invalid input
if flags == nil || req == nil {
return nil
}
var processors []preSearchResultProcessor
// Add KNN processor if the request has KNN
if flags.knn {
if knnProcessor := newKnnPreSearchResultProcessor(req); knnProcessor != nil {
processors = append(processors, knnProcessor)
}
}
// Add Synonym processor if the request has Synonym
if flags.synonyms {
if synonymProcessor := newSynonymPreSearchResultProcessor(); synonymProcessor != nil {
processors = append(processors, synonymProcessor)
}
}
// Return based on the number of processors, optimizing for the common case of 1 processor
// If there are no processors, return nil
switch len(processors) {
case 0:
return nil
case 1:
return processors[0]
default:
return &compositePreSearchResultProcessor{
presearchResultProcessors: processors,
}
}
}