2014-07-03 20:54:50 +02:00
// Copyright (c) 2013 Couchbase, Inc.
2016-10-02 16:13:14 +02:00
//
// 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.
2014-09-02 16:54:50 +02:00
2016-10-02 16:29:39 +02:00
package searcher
2014-07-03 20:54:50 +02:00
import (
2016-10-27 11:25:03 +02:00
"reflect"
2014-07-03 20:54:50 +02:00
"testing"
2014-09-01 17:15:38 +02:00
2016-08-01 20:26:50 +02:00
"github.com/blevesearch/bleve/index"
2014-09-01 17:15:38 +02:00
"github.com/blevesearch/bleve/search"
2014-07-03 20:54:50 +02:00
)
func TestPhraseSearch ( t * testing . T ) {
2014-10-31 14:40:23 +01:00
twoDocIndexReader , err := twoDocIndex . Reader ( )
if err != nil {
t . Error ( err )
}
2015-04-08 00:05:41 +02:00
defer func ( ) {
err := twoDocIndexReader . Close ( )
if err != nil {
t . Fatal ( err )
}
} ( )
2014-09-12 23:21:35 +02:00
2017-01-06 02:49:45 +01:00
soptions := search . SearcherOptions { Explain : true , IncludeTermVectors : true }
angstTermSearcher , err := NewTermSearcher ( twoDocIndexReader , "angst" , "desc" , 1.0 , soptions )
2014-07-30 18:30:38 +02:00
if err != nil {
t . Fatal ( err )
}
2017-01-06 02:49:45 +01:00
beerTermSearcher , err := NewTermSearcher ( twoDocIndexReader , "beer" , "desc" , 1.0 , soptions )
2014-07-30 18:30:38 +02:00
if err != nil {
t . Fatal ( err )
}
2017-01-06 02:49:45 +01:00
mustSearcher , err := NewConjunctionSearcher ( twoDocIndexReader , [ ] search . Searcher { angstTermSearcher , beerTermSearcher } , soptions )
2014-07-30 18:30:38 +02:00
if err != nil {
t . Fatal ( err )
}
2014-09-12 23:21:35 +02:00
phraseSearcher , err := NewPhraseSearcher ( twoDocIndexReader , mustSearcher , [ ] string { "angst" , "beer" } )
2014-07-30 18:30:38 +02:00
if err != nil {
t . Fatal ( err )
}
2014-07-03 20:54:50 +02:00
tests := [ ] struct {
2016-10-27 11:25:03 +02:00
searcher search . Searcher
results [ ] * search . DocumentMatch
locations map [ string ] map [ string ] [ ] search . Location
fieldterms [ ] [ 2 ] string
2014-07-03 20:54:50 +02:00
} {
{
2014-07-30 18:30:38 +02:00
searcher : phraseSearcher ,
2016-08-01 20:58:02 +02:00
results : [ ] * search . DocumentMatch {
2016-04-03 03:54:33 +02:00
{
2016-08-01 20:58:02 +02:00
IndexInternalID : index . IndexInternalID ( "2" ) ,
Score : 1.0807601687084403 ,
2014-07-03 20:54:50 +02:00
} ,
} ,
2016-10-27 11:25:03 +02:00
locations : map [ string ] map [ string ] [ ] search . Location { "desc" : map [ string ] [ ] search . Location { "beer" : [ ] search . Location { search . Location { Pos : 2 , Start : 6 , End : 10 , ArrayPositions : [ ] float64 ( nil ) } } , "angst" : [ ] search . Location { search . Location { Pos : 1 , Start : 0 , End : 5 , ArrayPositions : [ ] float64 ( nil ) } } } } ,
fieldterms : [ ] [ 2 ] string { [ 2 ] string { "desc" , "beer" } , [ 2 ] string { "desc" , "angst" } } ,
2014-07-03 20:54:50 +02:00
} ,
}
for testIndex , test := range tests {
2015-04-08 00:05:41 +02:00
defer func ( ) {
err := test . searcher . Close ( )
if err != nil {
t . Fatal ( err )
}
} ( )
2014-07-03 20:54:50 +02:00
2016-08-09 04:21:47 +02:00
ctx := & search . SearchContext {
2016-08-25 01:02:22 +02:00
DocumentMatchPool : search . NewDocumentMatchPool ( test . searcher . DocumentMatchPoolSize ( ) , 0 ) ,
2016-08-09 04:21:47 +02:00
}
next , err := test . searcher . Next ( ctx )
2014-07-03 20:54:50 +02:00
i := 0
for err == nil && next != nil {
if i < len ( test . results ) {
2016-08-01 20:58:02 +02:00
if ! next . IndexInternalID . Equals ( test . results [ i ] . IndexInternalID ) {
2016-10-27 11:25:03 +02:00
t . Errorf ( "expected result %d to have id %s got %s for test %d\n" , i , test . results [ i ] . IndexInternalID , next . IndexInternalID , testIndex )
2014-07-03 20:54:50 +02:00
}
if next . Score != test . results [ i ] . Score {
2016-10-27 11:25:03 +02:00
t . Errorf ( "expected result %d to have score %v got %v for test %d\n" , i , test . results [ i ] . Score , next . Score , testIndex )
t . Logf ( "scoring explanation: %s\n" , next . Expl )
}
for _ , ft := range test . fieldterms {
locs := next . Locations [ ft [ 0 ] ] [ ft [ 1 ] ]
explocs := test . locations [ ft [ 0 ] ] [ ft [ 1 ] ]
if len ( explocs ) != len ( locs ) {
t . Fatalf ( "expected result %d to have %d Locations (%#v) but got %d (%#v) for test %d with field %q and term %q\n" , i , len ( explocs ) , explocs , len ( locs ) , locs , testIndex , ft [ 0 ] , ft [ 1 ] )
}
for ind , exploc := range explocs {
if ! reflect . DeepEqual ( * locs [ ind ] , exploc ) {
t . Errorf ( "expected result %d to have Location %v got %v for test %d\n" , i , exploc , locs [ ind ] , testIndex )
}
}
2014-07-03 20:54:50 +02:00
}
}
2016-10-27 11:25:03 +02:00
2016-08-09 04:21:47 +02:00
ctx . DocumentMatchPool . Put ( next )
next , err = test . searcher . Next ( ctx )
2014-07-03 20:54:50 +02:00
i ++
}
if err != nil {
t . Fatalf ( "error iterating searcher: %v for test %d" , err , testIndex )
}
if len ( test . results ) != i {
t . Errorf ( "expected %d results got %d for test %d" , len ( test . results ) , i , testIndex )
}
}
}