0
0
Fork 0
bleve/search/searchers/search_docid.go

103 lines
2.5 KiB
Go
Raw Normal View History

// Copyright (c) 2015 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 searchers
import (
"sort"
"github.com/blevesearch/bleve/index"
"github.com/blevesearch/bleve/search"
"github.com/blevesearch/bleve/search/scorers"
)
// DocIDSearcher returns documents matching a predefined set of identifiers.
type DocIDSearcher struct {
ids []string
current int
scorer *scorers.ConstantScorer
}
func NewDocIDSearcher(indexReader index.IndexReader, ids []string, boost float64,
explain bool) (searcher *DocIDSearcher, err error) {
kept := make([]string, len(ids))
copy(kept, ids)
sort.Strings(kept)
if len(ids) > 0 {
var idReader index.DocIDReader
endTerm := string(incrementBytes([]byte(kept[len(kept)-1])))
idReader, err = indexReader.DocIDReader(kept[0], endTerm)
if err != nil {
return nil, err
}
defer func() {
if cerr := idReader.Close(); err == nil && cerr != nil {
err = cerr
}
}()
j := 0
for _, id := range kept {
doc, err := idReader.Advance(id)
if err != nil {
return nil, err
}
// Non-duplicate match
if doc == id && (j == 0 || kept[j-1] != id) {
kept[j] = id
j++
}
}
kept = kept[:j]
}
scorer := scorers.NewConstantScorer(1.0, boost, explain)
return &DocIDSearcher{
ids: kept,
scorer: scorer,
}, nil
}
func (s *DocIDSearcher) Count() uint64 {
return uint64(len(s.ids))
}
func (s *DocIDSearcher) Weight() float64 {
return s.scorer.Weight()
}
func (s *DocIDSearcher) SetQueryNorm(qnorm float64) {
s.scorer.SetQueryNorm(qnorm)
}
func (s *DocIDSearcher) Next(preAllocated *search.DocumentMatch) (*search.DocumentMatch, error) {
if s.current >= len(s.ids) {
return nil, nil
}
id := s.ids[s.current]
s.current++
docMatch := s.scorer.Score(id)
return docMatch, nil
}
func (s *DocIDSearcher) Advance(ID string, preAllocated *search.DocumentMatch) (*search.DocumentMatch, error) {
s.current = sort.SearchStrings(s.ids, ID)
return s.Next(preAllocated)
}
func (s *DocIDSearcher) Close() error {
return nil
}
func (s *DocIDSearcher) Min() int {
return 0
}