0
0
Fork 0

Make facets much faster

This commit is contained in:
slavikm 2016-07-17 15:31:35 -07:00
parent 412d50f1d7
commit 9a9b630a6d
7 changed files with 72 additions and 2 deletions

View File

@ -77,8 +77,10 @@ type IndexReader interface {
Document(id string) (*document.Document, error)
DocumentFieldTerms(id string) (FieldTerms, error)
DocumentFieldTermsForFields(id string, fieldIDs []uint16, fields []string) (FieldTerms, error)
Fields() ([]string, error)
FieldIDs(fields []string) ([]uint16, error)
GetInternal(key []byte) ([]byte, error)

View File

@ -13,6 +13,7 @@ import (
"github.com/blevesearch/bleve/document"
"github.com/blevesearch/bleve/index"
"github.com/blevesearch/bleve/index/store"
"fmt"
)
type IndexReader struct {
@ -110,6 +111,27 @@ func (i *IndexReader) DocumentFieldTerms(id string) (index.FieldTerms, error) {
return rv, nil
}
func (i *IndexReader) DocumentFieldTermsForFields(id string, fieldIDs []uint16, fields []string) (index.FieldTerms, error) {
back, err := i.index.backIndexRowForDoc(i.kvreader, id)
if err != nil {
return nil, err
}
rv := make(index.FieldTerms, len(fieldIDs))
for _, entry := range back.termEntries {
for id, field := range fieldIDs {
if field == uint16(*entry.Field) {
terms, ok := rv[fields[id]]
if !ok {
terms = make([]string, 0)
}
terms = append(terms, *entry.Term)
rv[fields[id]] = terms
}
}
}
return rv, nil
}
func (i *IndexReader) Fields() (fields []string, err error) {
fields = make([]string, 0)
it := i.kvreader.PrefixIterator([]byte{'f'})
@ -139,6 +161,17 @@ func (i *IndexReader) Fields() (fields []string, err error) {
return
}
func (i *IndexReader) FieldIDs(fields []string) (ids []uint16, err error) {
for _, f := range fields {
id, found := i.index.fieldCache.FieldNamed(f, false)
if !found {
return nil, fmt.Errorf("Field %s was not found in cache", f)
}
ids = append(ids, id)
}
return
}
func (i *IndexReader) GetInternal(key []byte) ([]byte, error) {
internalRow := NewInternalRow(key, nil)
return i.kvreader.Get(internalRow.Key())

View File

@ -191,6 +191,8 @@ func (h *HighlightRequest) AddField(field string) {
// Facets describe the set of facets to be computed.
// Explain triggers inclusion of additional search
// result score explanations.
// Sort specifies the sorting for the returned results
// results will be sorted by score if this is empty
//
// A special field named "*" can be used to return all fields.
type SearchRequest struct {
@ -201,6 +203,7 @@ type SearchRequest struct {
Fields []string `json:"fields"`
Facets FacetsRequest `json:"facets"`
Explain bool `json:"explain"`
Sort map[string]bool `json:"sort"`
}
func (sr *SearchRequest) Validate() error {
@ -220,6 +223,14 @@ func (r *SearchRequest) AddFacet(facetName string, f *FacetRequest) {
r.Facets[facetName] = f
}
// AddSort field in ascending or descending direction
func (r *SearchRequest) AddSort(field string, ascending bool) {
if r.Sort == nil {
r.Sort = make(map[string]bool)
}
r.Sort[field] = ascending
}
// UnmarshalJSON deserializes a JSON representation of
// a SearchRequest
func (r *SearchRequest) UnmarshalJSON(input []byte) error {
@ -231,6 +242,7 @@ func (r *SearchRequest) UnmarshalJSON(input []byte) error {
Fields []string `json:"fields"`
Facets FacetsRequest `json:"facets"`
Explain bool `json:"explain"`
Sort map[string]bool `json:"sort"`
}
err := json.Unmarshal(input, &temp)
@ -248,6 +260,7 @@ func (r *SearchRequest) UnmarshalJSON(input []byte) error {
r.Highlight = temp.Highlight
r.Fields = temp.Fields
r.Facets = temp.Facets
r.Sort = temp.Sort
r.Query, err = ParseQuery(temp.Q)
if err != nil {
return err
@ -280,6 +293,7 @@ func NewSearchRequestOptions(q Query, size, from int, explain bool) *SearchReque
Size: size,
From: from,
Explain: explain,
Sort: make(map[string]bool),
}
}
@ -307,7 +321,7 @@ func (iem IndexErrMap) UnmarshalJSON(data []byte) error {
return nil
}
// SearchStatus is a secion in the SearchResult reporting how many
// SearchStatus is a section in the SearchResult reporting how many
// underlying indexes were queried, how many were successful/failed
// and a map of any errors that were encountered
type SearchStatus struct {

View File

@ -49,6 +49,10 @@ func (fb *DateTimeFacetBuilder) AddRange(name string, start, end time.Time) {
fb.ranges[name] = &r
}
func (fb *DateTimeFacetBuilder) Field() string {
return fb.field
}
func (fb *DateTimeFacetBuilder) Update(ft index.FieldTerms) {
terms, ok := ft[fb.field]
if ok {

View File

@ -48,6 +48,10 @@ func (fb *NumericFacetBuilder) AddRange(name string, min, max *float64) {
fb.ranges[name] = &r
}
func (fb *NumericFacetBuilder) Field() string {
return fb.field
}
func (fb *NumericFacetBuilder) Update(ft index.FieldTerms) {
terms, ok := ft[fb.field]
if ok {

View File

@ -32,6 +32,10 @@ func NewTermsFacetBuilder(field string, size int) *TermsFacetBuilder {
}
}
func (fb *TermsFacetBuilder) Field() string {
return fb.field
}
func (fb *TermsFacetBuilder) Update(ft index.FieldTerms) {
terms, ok := ft[fb.field]
if ok {

View File

@ -18,6 +18,7 @@ import (
type FacetBuilder interface {
Update(index.FieldTerms)
Result() *FacetResult
Field() string
}
type FacetsBuilder struct {
@ -37,7 +38,15 @@ func (fb *FacetsBuilder) Add(name string, facetBuilder FacetBuilder) {
}
func (fb *FacetsBuilder) Update(docMatch *DocumentMatch) error {
fieldTerms, err := fb.indexReader.DocumentFieldTerms(docMatch.ID)
var fields []string
for _, facetBuilder := range fb.facets {
fields = append(fields, facetBuilder.Field())
}
fieldIds, err := fb.indexReader.FieldIDs(fields)
if err != nil {
return err
}
fieldTerms, err := fb.indexReader.DocumentFieldTermsForFields(docMatch.ID, fieldIds, fields)
if err != nil {
return err
}