0
0
Fork 0

add option for multi term searcher to skip max disjunction check

- geo searches now use this option and skip the check
- export ComputeGeoTerms for geo debug visualizations
This commit is contained in:
Marty Schoch 2017-04-04 10:46:57 -04:00
parent 7dd52a69d2
commit 6f62489f21
9 changed files with 48 additions and 27 deletions

View File

@ -50,11 +50,22 @@ func tooManyClauses(count int) bool {
}
func tooManyClausesErr() error {
return fmt.Errorf("TooManyClauses[maxClauseCount is set to %d]", DisjunctionMaxClauseCount)
return fmt.Errorf("TooManyClauses[maxClauseCount is set to %d]",
DisjunctionMaxClauseCount)
}
func NewDisjunctionSearcher(indexReader index.IndexReader, qsearchers []search.Searcher, min float64, options search.SearcherOptions) (*DisjunctionSearcher, error) {
if tooManyClauses(len(qsearchers)) {
func NewDisjunctionSearcher(indexReader index.IndexReader,
qsearchers []search.Searcher, min float64, options search.SearcherOptions) (
*DisjunctionSearcher, error) {
return newDisjunctionSearcher(indexReader, qsearchers, min, options,
true)
}
func newDisjunctionSearcher(indexReader index.IndexReader,
qsearchers []search.Searcher, min float64, options search.SearcherOptions,
limit bool) (
*DisjunctionSearcher, error) {
if limit && tooManyClauses(len(qsearchers)) {
return nil, tooManyClausesErr()
}
// build the downstream searchers
@ -161,7 +172,8 @@ func (s *DisjunctionSearcher) SetQueryNorm(qnorm float64) {
}
}
func (s *DisjunctionSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) {
func (s *DisjunctionSearcher) Next(ctx *search.SearchContext) (
*search.DocumentMatch, error) {
if !s.initialized {
err := s.initSearchers(ctx)
if err != nil {
@ -199,7 +211,8 @@ func (s *DisjunctionSearcher) Next(ctx *search.SearchContext) (*search.DocumentM
return rv, nil
}
func (s *DisjunctionSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) {
func (s *DisjunctionSearcher) Advance(ctx *search.SearchContext,
ID index.IndexInternalID) (*search.DocumentMatch, error) {
if !s.initialized {
err := s.initSearchers(ctx)
if err != nil {

View File

@ -39,7 +39,7 @@ func NewFuzzySearcher(indexReader index.IndexReader, term string,
}
return NewMultiTermSearcher(indexReader, candidateTerms, field,
boost, options)
boost, options, true)
}
func findFuzzyCandidateTerms(indexReader index.IndexReader, term string,

View File

@ -36,13 +36,13 @@ func NewGeoBoundingBoxSearcher(indexReader index.IndexReader, minLon, minLat,
}
// do math to produce list of terms needed for this search
onBoundaryTerms, notOnBoundaryTerms := computeRange(0, (geo.GeoBits<<1)-1,
onBoundaryTerms, notOnBoundaryTerms := ComputeGeoRange(0, (geo.GeoBits<<1)-1,
minLon, minLat, maxLon, maxLat, checkBoundaries)
var onBoundarySearcher search.Searcher
if len(onBoundaryTerms) > 0 {
rawOnBoundarySearcher, err := NewMultiTermSearcherBytes(indexReader,
onBoundaryTerms, field, boost, options)
onBoundaryTerms, field, boost, options, false)
if err != nil {
return nil, err
}
@ -56,7 +56,7 @@ func NewGeoBoundingBoxSearcher(indexReader index.IndexReader, minLon, minLat,
if len(notOnBoundaryTerms) > 0 {
var err error
notOnBoundarySearcher, err = NewMultiTermSearcherBytes(indexReader,
notOnBoundaryTerms, field, boost, options)
notOnBoundaryTerms, field, boost, options, false)
if err != nil {
cleanupOpenedSearchers()
return nil, err
@ -88,7 +88,7 @@ func NewGeoBoundingBoxSearcher(indexReader index.IndexReader, minLon, minLat,
var geoMaxShift = document.GeoPrecisionStep * 4
var geoDetailLevel = ((geo.GeoBits << 1) - geoMaxShift) / 2
func computeRange(term uint64, shift uint,
func ComputeGeoRange(term uint64, shift uint,
sminLon, sminLat, smaxLon, smaxLat float64,
checkBoundaries bool) (
onBoundary [][]byte, notOnBoundary [][]byte) {
@ -138,7 +138,7 @@ func relateAndRecurse(start, end uint64, res uint,
} else if level < geoDetailLevel &&
geo.RectIntersects(minLon, minLat, maxLon, maxLat,
sminLon, sminLat, smaxLon, smaxLat) {
return computeRange(start, res-1, sminLon, sminLat, smaxLon, smaxLat,
return ComputeGeoRange(start, res-1, sminLon, sminLat, smaxLon, smaxLat,
checkBoundaries)
}
return nil, nil

View File

@ -29,7 +29,7 @@ func NewGeoPointDistanceSearcher(indexReader index.IndexReader, centerLon,
topLeftLon, topLeftLat, bottomRightLon, bottomRightLat :=
geo.ComputeBoundingBox(centerLon, centerLat, dist)
// build a searcher for the box
// build a searcher for the box
boxSearcher, err := boxSearcher(indexReader,
topLeftLon, topLeftLat, bottomRightLon, bottomRightLat,
field, boost, options)

View File

@ -20,7 +20,7 @@ import (
)
func NewMultiTermSearcher(indexReader index.IndexReader, terms []string,
field string, boost float64, options search.SearcherOptions) (
field string, boost float64, options search.SearcherOptions, limit bool) (
search.Searcher, error) {
qsearchers := make([]search.Searcher, len(terms))
qsearchersClose := func() {
@ -39,17 +39,12 @@ func NewMultiTermSearcher(indexReader index.IndexReader, terms []string,
}
}
// build disjunction searcher of these ranges
searcher, err := NewDisjunctionSearcher(indexReader, qsearchers, 0, options)
if err != nil {
qsearchersClose()
return nil, err
}
return searcher, nil
return newMultiTermSearcherBytes(indexReader, qsearchers, field, boost,
options, limit)
}
func NewMultiTermSearcherBytes(indexReader index.IndexReader, terms [][]byte,
field string, boost float64, options search.SearcherOptions) (
field string, boost float64, options search.SearcherOptions, limit bool) (
search.Searcher, error) {
qsearchers := make([]search.Searcher, len(terms))
qsearchersClose := func() {
@ -67,10 +62,22 @@ func NewMultiTermSearcherBytes(indexReader index.IndexReader, terms [][]byte,
return nil, err
}
}
return newMultiTermSearcherBytes(indexReader, qsearchers, field, boost,
options, limit)
}
func newMultiTermSearcherBytes(indexReader index.IndexReader,
searchers []search.Searcher, field string, boost float64,
options search.SearcherOptions, limit bool) (
search.Searcher, error) {
// build disjunction searcher of these ranges
searcher, err := NewDisjunctionSearcher(indexReader, qsearchers, 0, options)
searcher, err := newDisjunctionSearcher(indexReader, searchers, 0, options,
limit)
if err != nil {
qsearchersClose()
for _, s := range searchers {
_ = s.Close()
}
return nil, err
}

View File

@ -59,7 +59,8 @@ func NewNumericRangeSearcher(indexReader index.IndexReader,
return nil, tooManyClausesErr()
}
return NewMultiTermSearcherBytes(indexReader, terms, field, boost, options)
return NewMultiTermSearcherBytes(indexReader, terms, field, boost, options,
true)
}
type termRange struct {

View File

@ -45,7 +45,7 @@ func NewRegexpSearcher(indexReader index.IndexReader, pattern *regexp.Regexp,
}
return NewMultiTermSearcher(indexReader, candidateTerms, field, boost,
options)
options, true)
}
func findRegexpCandidateTerms(indexReader index.IndexReader,

View File

@ -35,5 +35,5 @@ func NewTermPrefixSearcher(indexReader index.IndexReader, prefix string,
tfd, err = fieldDict.Next()
}
return NewMultiTermSearcher(indexReader, terms, field, boost, options)
return NewMultiTermSearcher(indexReader, terms, field, boost, options, true)
}

View File

@ -71,5 +71,5 @@ func NewTermRangeSearcher(indexReader index.IndexReader,
terms = terms[:len(terms)-1]
}
return NewMultiTermSearcher(indexReader, terms, field, boost, options)
return NewMultiTermSearcher(indexReader, terms, field, boost, options, true)
}