Search: Add substring matcher (#54895)
* Search: Add substring matcher (#54813) * search: bring back substring search * lint fix * search: bring back ngram * search: bring back ngram * search: more tests * fix tests
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
// based on https://github.com/blugelabs/bluge/blob/57414197005148539c5dc5db8ab581594969df79/query.go#L1407-L1482, license:
|
||||
// Copyright (c) 2020 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 searchV2
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/blugelabs/bluge/search"
|
||||
"github.com/blugelabs/bluge/search/searcher"
|
||||
"github.com/blugelabs/bluge/search/similarity"
|
||||
)
|
||||
|
||||
type boost float64
|
||||
|
||||
func (b *boost) Value() float64 {
|
||||
if b == nil {
|
||||
return 1
|
||||
}
|
||||
return float64(*b)
|
||||
}
|
||||
|
||||
type SubstringQuery struct {
|
||||
substring string
|
||||
field string
|
||||
boost *boost
|
||||
scorer search.Scorer
|
||||
}
|
||||
|
||||
func NewSubstringQuery(wildcard string) *SubstringQuery {
|
||||
return &SubstringQuery{
|
||||
substring: wildcard,
|
||||
}
|
||||
}
|
||||
|
||||
// Wildcard returns the substring being queried
|
||||
func (q *SubstringQuery) Wildcard() string {
|
||||
return q.substring
|
||||
}
|
||||
|
||||
func (q *SubstringQuery) SetBoost(b float64) *SubstringQuery {
|
||||
boostVal := boost(b)
|
||||
q.boost = &boostVal
|
||||
return q
|
||||
}
|
||||
|
||||
func (q *SubstringQuery) Boost() float64 {
|
||||
return q.boost.Value()
|
||||
}
|
||||
|
||||
func (q *SubstringQuery) SetField(f string) *SubstringQuery {
|
||||
q.field = f
|
||||
return q
|
||||
}
|
||||
|
||||
func (q *SubstringQuery) Field() string {
|
||||
return q.field
|
||||
}
|
||||
|
||||
var regexpEscaper = strings.NewReplacer(
|
||||
// characters in the substring that must
|
||||
// be escaped in the regexp
|
||||
"+", `\+`,
|
||||
"*", `\*`,
|
||||
"(", `\(`,
|
||||
")", `\)`,
|
||||
"^", `\^`,
|
||||
"$", `\$`,
|
||||
".", `\.`,
|
||||
"{", `\{`,
|
||||
"}", `\}`,
|
||||
"[", `\[`,
|
||||
"]", `\]`,
|
||||
`|`, `\|`,
|
||||
`\`, `\\`)
|
||||
|
||||
func (q *SubstringQuery) Searcher(i search.Reader, options search.SearcherOptions) (search.Searcher, error) {
|
||||
field := q.field
|
||||
if q.field == "" {
|
||||
field = options.DefaultSearchField
|
||||
}
|
||||
|
||||
regexpString := ".*" + regexpEscaper.Replace(q.substring) + ".*"
|
||||
return searcher.NewRegexpStringSearcher(i, regexpString, field,
|
||||
q.boost.Value(), q.scorer, similarity.NewCompositeSumScorer(), options)
|
||||
}
|
||||
|
||||
func (q *SubstringQuery) Validate() error {
|
||||
return nil // real validation delayed until searcher constructor
|
||||
}
|
||||
Reference in New Issue
Block a user