scorch conjuncts match phrase test passes
The conjunction searcher Advance() method now checks if its curr doc-matches suffices before advancing them.
This commit is contained in:
parent
903e8797c7
commit
c7a342bc7d
|
@ -343,6 +343,7 @@ func (i *IndexSnapshot) TermFieldReader(term []byte, field string, includeFreq,
|
||||||
|
|
||||||
rv := &IndexSnapshotTermFieldReader{
|
rv := &IndexSnapshotTermFieldReader{
|
||||||
term: term,
|
term: term,
|
||||||
|
field: field,
|
||||||
snapshot: i,
|
snapshot: i,
|
||||||
postings: make([]segment.PostingsList, len(i.segment)),
|
postings: make([]segment.PostingsList, len(i.segment)),
|
||||||
iterators: make([]segment.PostingsIterator, len(i.segment)),
|
iterators: make([]segment.PostingsIterator, len(i.segment)),
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
|
|
||||||
type IndexSnapshotTermFieldReader struct {
|
type IndexSnapshotTermFieldReader struct {
|
||||||
term []byte
|
term []byte
|
||||||
|
field string
|
||||||
snapshot *IndexSnapshot
|
snapshot *IndexSnapshot
|
||||||
postings []segment.PostingsList
|
postings []segment.PostingsList
|
||||||
iterators []segment.PostingsIterator
|
iterators []segment.PostingsIterator
|
||||||
|
@ -84,15 +85,15 @@ func (i *IndexSnapshotTermFieldReader) postingToTermFieldDoc(next segment.Postin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IndexSnapshotTermFieldReader) Advance(ID index.IndexInternalID, preAlloced *index.TermFieldDoc) (*index.TermFieldDoc, error) {
|
func (i *IndexSnapshotTermFieldReader) Advance(ID index.IndexInternalID, preAlloced *index.TermFieldDoc) (*index.TermFieldDoc, error) {
|
||||||
// first make sure we aren't already pointing at the right thing, (due to way searchers work)
|
// FIXME do something better
|
||||||
|
// for now, if we need to seek backwards, then restart from the beginning
|
||||||
if i.currPosting != nil && bytes.Compare(i.currID, ID) >= 0 {
|
if i.currPosting != nil && bytes.Compare(i.currID, ID) >= 0 {
|
||||||
rv := preAlloced
|
i2, err := i.snapshot.TermFieldReader(i.term, i.field,
|
||||||
if rv == nil {
|
i.includeFreq, i.includeNorm, i.includeTermVectors)
|
||||||
rv = &index.TermFieldDoc{}
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
rv.ID = i.currID
|
*i = *(i2.(*IndexSnapshotTermFieldReader))
|
||||||
i.postingToTermFieldDoc(i.currPosting, rv)
|
|
||||||
return rv, nil
|
|
||||||
}
|
}
|
||||||
// FIXME do something better
|
// FIXME do something better
|
||||||
next, err := i.Next(preAlloced)
|
next, err := i.Next(preAlloced)
|
||||||
|
|
|
@ -184,6 +184,9 @@ func (s *ConjunctionSearcher) Advance(ctx *search.SearchContext, ID index.IndexI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := range s.searchers {
|
for i := range s.searchers {
|
||||||
|
if s.currs[i] != nil && s.currs[i].IndexInternalID.Compare(ID) >= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
err := s.advanceChild(ctx, i, ID)
|
err := s.advanceChild(ctx, i, ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -313,6 +313,12 @@ func (s *PhraseSearcher) Advance(ctx *search.SearchContext, ID index.IndexIntern
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if s.currMust != nil {
|
||||||
|
if s.currMust.IndexInternalID.Compare(ID) >= 0 {
|
||||||
|
return s.Next(ctx)
|
||||||
|
}
|
||||||
|
ctx.DocumentMatchPool.Put(s.currMust)
|
||||||
|
}
|
||||||
var err error
|
var err error
|
||||||
s.currMust, err = s.mustSearcher.Advance(ctx, ID)
|
s.currMust, err = s.mustSearcher.Advance(ctx, ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -41,7 +41,7 @@ import (
|
||||||
// go test -v -run TestScorchVersusUpsideDownBolt ./test
|
// go test -v -run TestScorchVersusUpsideDownBolt ./test
|
||||||
// VERBOSE=1 FOCUS=Trista go test -v -run TestScorchVersusUpsideDownBolt ./test
|
// VERBOSE=1 FOCUS=Trista go test -v -run TestScorchVersusUpsideDownBolt ./test
|
||||||
//
|
//
|
||||||
func TestScorchVersusUpsideDownBolt(t *testing.T) {
|
func TestScorchVersusUpsideDownBoltAll(t *testing.T) {
|
||||||
(&VersusTest{
|
(&VersusTest{
|
||||||
t: t,
|
t: t,
|
||||||
NumDocs: 1000,
|
NumDocs: 1000,
|
||||||
|
@ -49,7 +49,7 @@ func TestScorchVersusUpsideDownBolt(t *testing.T) {
|
||||||
NumWords: 10,
|
NumWords: 10,
|
||||||
BatchSize: 10,
|
BatchSize: 10,
|
||||||
NumAttemptsPerSearch: 100,
|
NumAttemptsPerSearch: 100,
|
||||||
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil)
|
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScorchVersusUpsideDownBoltSmallMNSAM(t *testing.T) {
|
func TestScorchVersusUpsideDownBoltSmallMNSAM(t *testing.T) {
|
||||||
|
@ -61,13 +61,25 @@ func TestScorchVersusUpsideDownBoltSmallMNSAM(t *testing.T) {
|
||||||
NumWords: 1,
|
NumWords: 1,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
NumAttemptsPerSearch: 1,
|
NumAttemptsPerSearch: 1,
|
||||||
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil)
|
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestScorchVersusUpsideDownBoltSmallCMP11(t *testing.T) {
|
||||||
|
(&VersusTest{
|
||||||
|
t: t,
|
||||||
|
Focus: "conjuncts-match-phrase-1-1",
|
||||||
|
NumDocs: 30,
|
||||||
|
MaxWordsPerDoc: 8,
|
||||||
|
NumWords: 2,
|
||||||
|
BatchSize: 1,
|
||||||
|
NumAttemptsPerSearch: 1,
|
||||||
|
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|
||||||
// Templates used to compare search results in the "versus" tests.
|
// Templates used to compare search results in the "versus" tests.
|
||||||
var searchTemplates = []string{
|
var testVersusSearchTemplates = []string{
|
||||||
`{
|
`{
|
||||||
"about": "expected to return zero hits",
|
"about": "expected to return zero hits",
|
||||||
"query": {
|
"query": {
|
||||||
|
@ -130,7 +142,7 @@ var searchTemplates = []string{
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
`{
|
`{
|
||||||
"about": "must-not-only -- FAILS!!!",
|
"about": "must-not-only",
|
||||||
"query": {
|
"query": {
|
||||||
"must_not": {"disjuncts": [
|
"must_not": {"disjuncts": [
|
||||||
{"field": "body", "term": "{{word}}"}
|
{"field": "body", "term": "{{word}}"}
|
||||||
|
@ -172,6 +184,24 @@ var searchTemplates = []string{
|
||||||
]}
|
]}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
|
`{
|
||||||
|
"about": "conjuncts-match-phrase-1-1 inspired by testrunner RQG issue -- see: MB-27291",
|
||||||
|
"query": {
|
||||||
|
"conjuncts": [
|
||||||
|
{"field": "body", "match": "{{bodyWord 0}}"},
|
||||||
|
{"field": "body", "match_phrase": "{{bodyWord 1}} {{bodyWord 1}}"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
`{
|
||||||
|
"about": "conjuncts-match-phrase-1-2 inspired by testrunner RQG issue -- see: MB-27291 -- FAILS!!",
|
||||||
|
"query": {
|
||||||
|
"conjuncts": [
|
||||||
|
{"field": "body", "match": "{{bodyWord 0}}"},
|
||||||
|
{"field": "body", "match_phrase": "{{bodyWord 1}} {{bodyWord 2}}"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
@ -203,13 +233,25 @@ type VersusTest struct {
|
||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|
||||||
func testVersusSearches(vt *VersusTest, idxA, idxB bleve.Index) {
|
func testVersusSearches(vt *VersusTest, searchTemplates []string, idxA, idxB bleve.Index) {
|
||||||
t := vt.t
|
t := vt.t
|
||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
|
// Returns a word. The word may or may not be in any
|
||||||
|
// document's body.
|
||||||
"word": func() string {
|
"word": func() string {
|
||||||
return vt.genWord(vt.CurAttempt % vt.NumWords)
|
return vt.genWord(vt.CurAttempt % vt.NumWords)
|
||||||
},
|
},
|
||||||
|
// Picks a document and returns the i'th word in that
|
||||||
|
// document's body. You can use this in searches to
|
||||||
|
// definitely find at least one document.
|
||||||
|
"bodyWord": func(i int) string {
|
||||||
|
body := vt.Bodies[vt.CurAttempt%len(vt.Bodies)]
|
||||||
|
if len(body) <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return body[i%len(body)]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optionally allow call to focus on a particular search templates,
|
// Optionally allow call to focus on a particular search templates,
|
||||||
|
@ -275,16 +317,24 @@ func testVersusSearches(vt *VersusTest, idxA, idxB bleve.Index) {
|
||||||
hitsA := hitsById(resA)
|
hitsA := hitsById(resA)
|
||||||
hitsB := hitsById(resB)
|
hitsB := hitsById(resB)
|
||||||
if !reflect.DeepEqual(hitsA, hitsB) {
|
if !reflect.DeepEqual(hitsA, hitsB) {
|
||||||
t.Errorf("search: (%d) %s,\n res hits mismatch,\n len(hitsA): %d,\n len(hitsB): %d",
|
t.Errorf("=========\nsearch: (%d) %s,\n res hits mismatch,\n len(hitsA): %d,\n len(hitsB): %d",
|
||||||
i, bufBytes, len(hitsA), len(hitsB))
|
i, bufBytes, len(hitsA), len(hitsB))
|
||||||
t.Errorf("\n hitsA: %#v,\n hitsB: %#v",
|
t.Errorf("\n hitsA: %#v,\n hitsB: %#v",
|
||||||
hitsA, hitsB)
|
hitsA, hitsB)
|
||||||
for id, hitA := range hitsA {
|
for id, hitA := range hitsA {
|
||||||
hitB := hitsB[id]
|
hitB := hitsB[id]
|
||||||
if !reflect.DeepEqual(hitA, hitB) {
|
if !reflect.DeepEqual(hitA, hitB) {
|
||||||
t.Errorf("\n hitA: %#v,\n hitB: %#v", hitA, hitB)
|
t.Errorf("\n driving from hitsA\n hitA: %#v,\n hitB: %#v", hitA, hitB)
|
||||||
idx, _ := strconv.Atoi(id)
|
idx, _ := strconv.Atoi(id)
|
||||||
t.Errorf("\n body: %s", strings.Join(vt.Bodies[idx], " "))
|
t.Errorf("\n doc: %d, body: %s", idx, strings.Join(vt.Bodies[idx], " "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for id, hitB := range hitsB {
|
||||||
|
hitA := hitsA[id]
|
||||||
|
if !reflect.DeepEqual(hitA, hitB) {
|
||||||
|
t.Errorf("\n driving from hitsB\n hitA: %#v,\n hitB: %#v", hitA, hitB)
|
||||||
|
idx, _ := strconv.Atoi(id)
|
||||||
|
t.Errorf("\n doc: %d, body: %s", idx, strings.Join(vt.Bodies[idx], " "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +345,7 @@ func testVersusSearches(vt *VersusTest, idxA, idxB bleve.Index) {
|
||||||
if !reflect.DeepEqual(resA, resB) {
|
if !reflect.DeepEqual(resA, resB) {
|
||||||
resAj, _ := json.Marshal(resA)
|
resAj, _ := json.Marshal(resA)
|
||||||
resBj, _ := json.Marshal(resB)
|
resBj, _ := json.Marshal(resB)
|
||||||
t.Errorf("search: (%d) %s,\n res mismatch,\n resA: %s,\n resB: %s",
|
t.Errorf("search: (%d) %s,\n res mismatch,\n resA: %s,\n resB: %s",
|
||||||
i, bufBytes, resAj, resBj)
|
i, bufBytes, resAj, resBj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,11 +379,16 @@ func hitsById(res *bleve.SearchResult) map[string]*search.DocumentMatch {
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|
||||||
func (vt *VersusTest) run(indexTypeA, kvStoreA, indexTypeB, kvStoreB string,
|
func (vt *VersusTest) run(indexTypeA, kvStoreA, indexTypeB, kvStoreB string,
|
||||||
cb func(versusTest *VersusTest, idxA, idxB bleve.Index)) {
|
cb func(versusTest *VersusTest, searchTemplates []string, idxA, idxB bleve.Index),
|
||||||
|
searchTemplates []string) {
|
||||||
if cb == nil {
|
if cb == nil {
|
||||||
cb = testVersusSearches
|
cb = testVersusSearches
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if searchTemplates == nil {
|
||||||
|
searchTemplates = testVersusSearchTemplates
|
||||||
|
}
|
||||||
|
|
||||||
if vt.Verbose <= 0 {
|
if vt.Verbose <= 0 {
|
||||||
vt.Verbose, _ = strconv.Atoi(os.Getenv("VERBOSE"))
|
vt.Verbose, _ = strconv.Atoi(os.Getenv("VERBOSE"))
|
||||||
}
|
}
|
||||||
|
@ -369,12 +424,14 @@ func (vt *VersusTest) run(indexTypeA, kvStoreA, indexTypeB, kvStoreB string,
|
||||||
|
|
||||||
rand.Seed(0)
|
rand.Seed(0)
|
||||||
|
|
||||||
vt.Bodies = vt.genBodies()
|
if vt.Bodies == nil {
|
||||||
|
vt.Bodies = vt.genBodies()
|
||||||
|
}
|
||||||
|
|
||||||
vt.insertBodies(idxA)
|
vt.insertBodies(idxA)
|
||||||
vt.insertBodies(idxB)
|
vt.insertBodies(idxB)
|
||||||
|
|
||||||
cb(vt, idxA, idxB)
|
cb(vt, searchTemplates, idxA, idxB)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue