Merge pull request #525 from mschoch/refactor-phrase
refactor phrase search into seprate methods
This commit is contained in:
commit
a3ee71ddbb
|
@ -96,56 +96,10 @@ func (s *PhraseSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var rv *search.DocumentMatch
|
|
||||||
for s.currMust != nil {
|
for s.currMust != nil {
|
||||||
rvftlm := make(search.FieldTermLocationMap, 0)
|
rv := s.checkCurrMustMatch(ctx)
|
||||||
freq := 0
|
if rv != nil {
|
||||||
firstTerm := s.terms[0]
|
// prepare for next iteration
|
||||||
for field, termLocMap := range s.currMust.Locations {
|
|
||||||
locations, ok := termLocMap[firstTerm]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
rvtlm := make(search.TermLocationMap, 0)
|
|
||||||
|
|
||||||
OUTER:
|
|
||||||
for _, location := range locations {
|
|
||||||
crvtlm := make(search.TermLocationMap, 0)
|
|
||||||
crvtlm.AddLocation(firstTerm, location)
|
|
||||||
INNER:
|
|
||||||
for i := 1; i < len(s.terms); i++ {
|
|
||||||
nextTerm := s.terms[i]
|
|
||||||
if nextTerm == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// look through all these term locations
|
|
||||||
// to try and find the correct offsets
|
|
||||||
nextLocations, ok := termLocMap[nextTerm]
|
|
||||||
if !ok {
|
|
||||||
continue OUTER
|
|
||||||
}
|
|
||||||
for _, nextLocation := range nextLocations {
|
|
||||||
if nextLocation.Pos == location.Pos+float64(i) && nextLocation.SameArrayElement(location) {
|
|
||||||
// found a location match for this term
|
|
||||||
crvtlm.AddLocation(nextTerm, nextLocation)
|
|
||||||
continue INNER
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if we got here we didn't find a location match for this term
|
|
||||||
continue OUTER
|
|
||||||
}
|
|
||||||
// if we got here all the terms matched
|
|
||||||
freq++
|
|
||||||
search.MergeTermLocationMaps(rvtlm, crvtlm)
|
|
||||||
rvftlm[field] = rvtlm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if freq > 0 {
|
|
||||||
// return match
|
|
||||||
rv = s.currMust
|
|
||||||
rv.Locations = rvftlm
|
|
||||||
err := s.advanceNextMust(ctx)
|
err := s.advanceNextMust(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -162,6 +116,86 @@ func (s *PhraseSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkCurrMustMatch is soley concerned with determining if the DocumentMatch
|
||||||
|
// pointed to by s.currMust (which satisifies the pre-condition searcher)
|
||||||
|
// also satisfies the phase constraints. if so, it returns a DocumentMatch
|
||||||
|
// for this document, otherwise nil
|
||||||
|
func (s *PhraseSearcher) checkCurrMustMatch(ctx *search.SearchContext) *search.DocumentMatch {
|
||||||
|
rvftlm := make(search.FieldTermLocationMap, 0)
|
||||||
|
freq := 0
|
||||||
|
// typically we would expect there to only actually be results in
|
||||||
|
// one field, but we allow for this to not be the case
|
||||||
|
// but, we note that phrase constraints can only be satisfied within
|
||||||
|
// a single field, so we can check them each independently
|
||||||
|
for field := range s.currMust.Locations {
|
||||||
|
|
||||||
|
f, rvtlm := s.checkCurrMustMatchField(ctx, field)
|
||||||
|
if f > 0 {
|
||||||
|
freq += f
|
||||||
|
rvftlm[field] = rvtlm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if freq > 0 {
|
||||||
|
// return match
|
||||||
|
rv := s.currMust
|
||||||
|
rv.Locations = rvftlm
|
||||||
|
return rv
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkCurrMustMatchField is soley concerned with determining if one particular
|
||||||
|
// field within the currMust DocumentMatch Locations satisfies the phase
|
||||||
|
// constraints (possibly more than once). if so, the number of times it was
|
||||||
|
// satisfied, and these locations are returned. otherwise 0 and either
|
||||||
|
// a nil or empty TermLocationMap
|
||||||
|
func (s *PhraseSearcher) checkCurrMustMatchField(ctx *search.SearchContext, field string) (int, search.TermLocationMap) {
|
||||||
|
firstTerm := s.terms[0]
|
||||||
|
freq := 0
|
||||||
|
termLocMap := s.currMust.Locations[field]
|
||||||
|
locations, ok := termLocMap[firstTerm]
|
||||||
|
if !ok {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rvtlm := make(search.TermLocationMap, 0)
|
||||||
|
|
||||||
|
OUTER:
|
||||||
|
for _, location := range locations {
|
||||||
|
crvtlm := make(search.TermLocationMap, 0)
|
||||||
|
crvtlm.AddLocation(firstTerm, location)
|
||||||
|
INNER:
|
||||||
|
for i := 1; i < len(s.terms); i++ {
|
||||||
|
nextTerm := s.terms[i]
|
||||||
|
if nextTerm == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// look through all these term locations
|
||||||
|
// to try and find the correct offsets
|
||||||
|
nextLocations, ok := termLocMap[nextTerm]
|
||||||
|
if !ok {
|
||||||
|
continue OUTER
|
||||||
|
}
|
||||||
|
for _, nextLocation := range nextLocations {
|
||||||
|
if nextLocation.Pos == location.Pos+float64(i) && nextLocation.SameArrayElement(location) {
|
||||||
|
// found a location match for this term
|
||||||
|
crvtlm.AddLocation(nextTerm, nextLocation)
|
||||||
|
continue INNER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if we got here we didn't find a location match for this term
|
||||||
|
continue OUTER
|
||||||
|
}
|
||||||
|
// if we got here all the terms matched
|
||||||
|
freq++
|
||||||
|
search.MergeTermLocationMaps(rvtlm, crvtlm)
|
||||||
|
}
|
||||||
|
|
||||||
|
return freq, rvtlm
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PhraseSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) {
|
func (s *PhraseSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) {
|
||||||
if !s.initialized {
|
if !s.initialized {
|
||||||
err := s.initSearchers(ctx)
|
err := s.initSearchers(ctx)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user