From e97c5b6955a09976adc95d48c14624fa9ac12750 Mon Sep 17 00:00:00 2001 From: Mikhail Iudin Date: Mon, 4 Nov 2024 22:10:15 +0100 Subject: [PATCH 1/2] Add weights --- bindings.h | 1 + example/main.go | 9 ++- rust/src/c_util/util.rs | 45 +++++++++++++- rust/src/lib.rs | 4 +- searchcontext.go | 127 ++++++++++++++++++++++++++++++++++++++++ tantivycontext.go | 15 +++-- 6 files changed, 192 insertions(+), 9 deletions(-) create mode 100644 searchcontext.go diff --git a/bindings.h b/bindings.h index 47ec75c..2bc402a 100644 --- a/bindings.h +++ b/bindings.h @@ -73,6 +73,7 @@ uint64_t context_num_docs(struct TantivyContext *context_ptr, char **error_buffe struct SearchResult *context_search(struct TantivyContext *context_ptr, const char **field_names_ptr, + float *field_weights_ptr, uintptr_t field_names_len, const char *query_ptr, char **error_buffer, diff --git a/example/main.go b/example/main.go index d8ea5a9..8598f51 100644 --- a/example/main.go +++ b/example/main.go @@ -135,7 +135,14 @@ func main() { } // Search index - result, err := index.Search("body", 100, true, NameBody) + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("body"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldWithoutWeight(NameBody). + Build() + + result, err := index.Search(sCtx) if err != nil { fmt.Println("Failed to search index:", err) return diff --git a/rust/src/c_util/util.rs b/rust/src/c_util/util.rs index e6a9754..3176036 100644 --- a/rust/src/c_util/util.rs +++ b/rust/src/c_util/util.rs @@ -1,13 +1,13 @@ use std::{fs, panic, slice}; use std::collections::HashMap; use std::ffi::{CStr, CString}; -use std::os::raw::c_char; +use std::os::raw::{c_char, c_float}; use std::path::Path; use std::sync::Mutex; use lazy_static::lazy_static; use log::debug; use serde_json::json; -use tantivy::{Index, IndexWriter, TantivyDocument, TantivyError, Term}; +use tantivy::{Index, IndexWriter, Score, TantivyDocument, TantivyError, Term}; use tantivy::directory::MmapDirectory; use tantivy::query::{QueryParser}; use tantivy::schema::{Field, Schema}; @@ -133,6 +133,30 @@ where Ok(()) } +pub fn process_slice<'a, F, T>( + ptr: *mut T, + error_buffer: *mut *mut c_char, + len: usize, + mut func: F, +) -> Result<(), ()> +where + F: FnMut(T) -> Result<(), ()>, + T: Copy, +{ + let slice = match assert_pointer(ptr, error_buffer) { + Some(ptr) => unsafe { slice::from_raw_parts(ptr, len) }, + None => return Err(()), + }; + + for item in slice { + if func(*item).is_err() { + return Err(()); + } + } + + Ok(()) +} + pub fn schema_apply_for_field<'a, T, K, F: FnMut(Field, &'a str) -> Result>( error_buffer: *mut *mut c_char, schema: Schema, @@ -350,6 +374,7 @@ pub fn add_field( pub fn search( field_names_ptr: *mut *const c_char, + field_weights_ptr: *mut c_float, field_names_len: usize, query_ptr: *const c_char, error_buffer: *mut *mut c_char, @@ -372,12 +397,26 @@ pub fn search( return Err(()); } + let mut weights = HashMap::with_capacity(field_names_len); + + let iter = 0; + if process_slice(field_weights_ptr, error_buffer, field_names_len, |field_weight| { + weights.insert(fields[iter], field_weight); + debug!("weights azaza: {:?}", weights); + Ok(()) + }).is_err() { + return Err(()); + } + let query = match assert_string(query_ptr, error_buffer) { Some(value) => value, None => return Err(()) }; - let query_parser = QueryParser::for_index(&context.index, fields); + let mut query_parser = QueryParser::for_index(&context.index, fields); + for (field, weight) in weights { + query_parser.set_field_boost(field, weight as Score); + } let query = match query_parser.parse_query(query.as_str()) { Ok(query) => query, diff --git a/rust/src/lib.rs b/rust/src/lib.rs index f962359..71c7070 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,5 +1,5 @@ use std::ffi::CString; -use std::os::raw::c_char; +use std::os::raw::{c_char, c_float}; use std::ptr; use logcall::logcall; use tantivy::{schema::*}; @@ -284,6 +284,7 @@ pub extern "C" fn context_num_docs( pub extern "C" fn context_search( context_ptr: *mut TantivyContext, field_names_ptr: *mut *const c_char, + field_weights_ptr: *mut c_float, field_names_len: usize, query_ptr: *const c_char, error_buffer: *mut *mut c_char, @@ -297,6 +298,7 @@ pub extern "C" fn context_search( match search( field_names_ptr, + field_weights_ptr, field_names_len, query_ptr, error_buffer, diff --git a/searchcontext.go b/searchcontext.go new file mode 100644 index 0000000..1623711 --- /dev/null +++ b/searchcontext.go @@ -0,0 +1,127 @@ +package tantivy_go + +import "fmt" + +// SearchContext defines the interface for searchContext +type SearchContext interface { + // GetQuery returns the search query string. + GetQuery() string + // GetDocsLimit returns the document limit as a uintptr. + GetDocsLimit() uintptr + // WithHighlights returns true if highlights are enabled. + WithHighlights() bool + // GetFieldWeights returns slices of field names and their corresponding weights. + GetFieldWeights() ([]string, []float32) +} + +// searchContext is a structure that implements SearchContext. +type searchContext struct { + query string + docsLimit uintptr + withHighlights bool + fieldNames map[string]float32 +} + +// GetQuery returns the search query string. +func (sc *searchContext) GetQuery() string { + return sc.query +} + +// GetDocsLimit returns the document limit. +func (sc *searchContext) GetDocsLimit() uintptr { + return sc.docsLimit +} + +// WithHighlights returns the highlights flag. +func (sc *searchContext) WithHighlights() bool { + return sc.withHighlights +} + +// GetFieldNames returns a map of field names and their weights. +func (sc *searchContext) GetFieldNames() map[string]float32 { + return sc.fieldNames +} + +// GetFieldWeights returns slices of field names and their corresponding weights. +func (sc *searchContext) GetFieldWeights() ([]string, []float32) { + fields := make([]string, 0, len(sc.fieldNames)) + weights := make([]float32, 0, len(sc.fieldNames)) + + for field, weight := range sc.fieldNames { + fields = append(fields, field) + weights = append(weights, weight) + } + + return fields, weights +} + +// SearchContextBuilder is a builder structure for creating searchContext. +type SearchContextBuilder struct { + context *searchContext +} + +// NewSearchContextBuilder creates a new instance of SearchContextBuilder. +func NewSearchContextBuilder() *SearchContextBuilder { + return &SearchContextBuilder{ + context: &searchContext{ + fieldNames: make(map[string]float32), + }, + } +} + +// SetQuery sets the query for searchContext. +func (b *SearchContextBuilder) SetQuery(query string) *SearchContextBuilder { + b.context.query = query + return b +} + +// SetDocsLimit sets the docsLimit for searchContext. +func (b *SearchContextBuilder) SetDocsLimit(limit uintptr) *SearchContextBuilder { + b.context.docsLimit = limit + return b +} + +// SetWithHighlights sets the withHighlights flag for searchContext. +func (b *SearchContextBuilder) SetWithHighlights(withHighlights bool) *SearchContextBuilder { + b.context.withHighlights = withHighlights + return b +} + +// AddField adds a field with the specified weight to searchContext. +func (b *SearchContextBuilder) AddField(field string, weight float32) *SearchContextBuilder { + b.context.fieldNames[field] = weight + return b +} + +// AddFieldWithoutWeight adds a field with a default weight of 1.0 to searchContext. +func (b *SearchContextBuilder) AddFieldWithoutWeight(field string) *SearchContextBuilder { + b.context.fieldNames[field] = 1.0 + return b +} + +// Build returns the constructed searchContext as an interface. +func (b *SearchContextBuilder) Build() SearchContext { + return b.context +} + +// Example usage of the searchContext and SearchContextBuilder. +func main() { + builder := NewSearchContextBuilder() + searchContext := builder. + SetQuery("example search query"). + SetDocsLimit(10). + SetWithHighlights(true). + AddField("title", 1.5). + AddFieldWithoutWeight("description"). + Build() + + // Retrieve fields and weights + fields, weights := searchContext.GetFieldWeights() + fmt.Printf("Fields: %v\n", fields) + fmt.Printf("Weights: %v\n", weights) + + // Additional information + fmt.Printf("searchContext Query: %s\n", searchContext.GetQuery()) + fmt.Printf("Docs Limit: %d\n", searchContext.GetDocsLimit()) + fmt.Printf("With Highlights: %t\n", searchContext.WithHighlights()) +} diff --git a/tantivycontext.go b/tantivycontext.go index 1ebdef4..42c4a72 100644 --- a/tantivycontext.go +++ b/tantivycontext.go @@ -120,11 +120,12 @@ func (tc *TantivyContext) NumDocs() (uint64, error) { // Returns: // - *SearchResult: A pointer to the SearchResult containing the search results. // - error: An error if the search fails. -func (tc *TantivyContext) Search(query string, docsLimit uintptr, withHighlights bool, fieldNames ...string) (*SearchResult, error) { +func (tc *TantivyContext) Search(sCtx SearchContext) (*SearchResult, error) { + fieldNames, weights := sCtx.GetFieldWeights() if len(fieldNames) == 0 { return nil, fmt.Errorf("fieldNames must not be empty") } - cQuery := C.CString(query) + cQuery := C.CString(sCtx.GetQuery()) defer C.string_free(cQuery) fieldNamesPtr := make([]*C.char, len(fieldNames)) @@ -134,15 +135,21 @@ func (tc *TantivyContext) Search(query string, docsLimit uintptr, withHighlights fieldNamesPtr[j] = cId } + fieldWeightsPtr := make([]C.float, len(fieldNames)) + for j, weight := range weights { + fieldWeightsPtr[j] = C.float(weight) + } + var errBuffer *C.char ptr := C.context_search( tc.ptr, (**C.char)(unsafe.Pointer(&fieldNamesPtr[0])), + (*C.float)(unsafe.Pointer(&fieldWeightsPtr[0])), C.uintptr_t(len(fieldNames)), cQuery, &errBuffer, - pointerCType(docsLimit), - C.bool(withHighlights), + pointerCType(sCtx.GetDocsLimit()), + C.bool(sCtx.WithHighlights()), ) if ptr == nil { defer C.string_free(errBuffer) From 134cb29625eaca02a0d2e0e020fe502590e99cb3 Mon Sep 17 00:00:00 2001 From: Mikhail Iudin Date: Tue, 5 Nov 2024 14:57:57 +0100 Subject: [PATCH 2/2] Add weights --- example/main.go | 2 +- rust/src/c_util/util.rs | 20 +++--- searchcontext.go | 34 ++------- tantivy_test.go | 151 +++++++++++++++++++++++++++++++++++----- tantivycontext.go | 8 +-- 5 files changed, 153 insertions(+), 62 deletions(-) diff --git a/example/main.go b/example/main.go index 8598f51..2debea7 100644 --- a/example/main.go +++ b/example/main.go @@ -139,7 +139,7 @@ func main() { SetQuery("body"). SetDocsLimit(100). SetWithHighlights(true). - AddFieldWithoutWeight(NameBody). + AddFieldDefaultWeight(NameBody). Build() result, err := index.Search(sCtx) diff --git a/rust/src/c_util/util.rs b/rust/src/c_util/util.rs index 3176036..d9749ad 100644 --- a/rust/src/c_util/util.rs +++ b/rust/src/c_util/util.rs @@ -140,7 +140,7 @@ pub fn process_slice<'a, F, T>( mut func: F, ) -> Result<(), ()> where - F: FnMut(T) -> Result<(), ()>, + F: FnMut(usize, T) -> Result<(), ()>, T: Copy, { let slice = match assert_pointer(ptr, error_buffer) { @@ -148,8 +148,8 @@ where None => return Err(()), }; - for item in slice { - if func(*item).is_err() { + for (i, item) in slice.iter().enumerate() { + if func(i, *item).is_err() { return Err(()); } } @@ -307,10 +307,10 @@ pub fn delete_docs( let field = match schema_apply_for_field:: (error_buffer, schema.clone(), field_name, |field, _| - match get_string_field_entry(schema.clone(), field) { - Ok(value) => Ok(value), - Err(_) => Err(()) - }, + match get_string_field_entry(schema.clone(), field) { + Ok(value) => Ok(value), + Err(_) => Err(()) + }, ) { Ok(value) => value, Err(_) => { @@ -399,10 +399,8 @@ pub fn search( let mut weights = HashMap::with_capacity(field_names_len); - let iter = 0; - if process_slice(field_weights_ptr, error_buffer, field_names_len, |field_weight| { - weights.insert(fields[iter], field_weight); - debug!("weights azaza: {:?}", weights); + if process_slice(field_weights_ptr, error_buffer, field_names_len, |i, field_weight| { + weights.insert(fields[i], field_weight); Ok(()) }).is_err() { return Err(()); diff --git a/searchcontext.go b/searchcontext.go index 1623711..527a9be 100644 --- a/searchcontext.go +++ b/searchcontext.go @@ -1,7 +1,5 @@ package tantivy_go -import "fmt" - // SearchContext defines the interface for searchContext type SearchContext interface { // GetQuery returns the search query string. @@ -10,8 +8,8 @@ type SearchContext interface { GetDocsLimit() uintptr // WithHighlights returns true if highlights are enabled. WithHighlights() bool - // GetFieldWeights returns slices of field names and their corresponding weights. - GetFieldWeights() ([]string, []float32) + // GetFieldAndWeights returns slices of field names and their corresponding weights. + GetFieldAndWeights() ([]string, []float32) } // searchContext is a structure that implements SearchContext. @@ -43,7 +41,7 @@ func (sc *searchContext) GetFieldNames() map[string]float32 { } // GetFieldWeights returns slices of field names and their corresponding weights. -func (sc *searchContext) GetFieldWeights() ([]string, []float32) { +func (sc *searchContext) GetFieldAndWeights() ([]string, []float32) { fields := make([]string, 0, len(sc.fieldNames)) weights := make([]float32, 0, len(sc.fieldNames)) @@ -93,8 +91,8 @@ func (b *SearchContextBuilder) AddField(field string, weight float32) *SearchCon return b } -// AddFieldWithoutWeight adds a field with a default weight of 1.0 to searchContext. -func (b *SearchContextBuilder) AddFieldWithoutWeight(field string) *SearchContextBuilder { +// AddFieldDefaultWeight adds a field with a default weight of 1.0 to searchContext. +func (b *SearchContextBuilder) AddFieldDefaultWeight(field string) *SearchContextBuilder { b.context.fieldNames[field] = 1.0 return b } @@ -103,25 +101,3 @@ func (b *SearchContextBuilder) AddFieldWithoutWeight(field string) *SearchContex func (b *SearchContextBuilder) Build() SearchContext { return b.context } - -// Example usage of the searchContext and SearchContextBuilder. -func main() { - builder := NewSearchContextBuilder() - searchContext := builder. - SetQuery("example search query"). - SetDocsLimit(10). - SetWithHighlights(true). - AddField("title", 1.5). - AddFieldWithoutWeight("description"). - Build() - - // Retrieve fields and weights - fields, weights := searchContext.GetFieldWeights() - fmt.Printf("Fields: %v\n", fields) - fmt.Printf("Weights: %v\n", weights) - - // Additional information - fmt.Printf("searchContext Query: %s\n", searchContext.GetQuery()) - fmt.Printf("Docs Limit: %d\n", searchContext.GetDocsLimit()) - fmt.Printf("With Highlights: %t\n", searchContext.WithHighlights()) -} diff --git a/tantivy_test.go b/tantivy_test.go index f88192c..5894c25 100644 --- a/tantivy_test.go +++ b/tantivy_test.go @@ -15,8 +15,8 @@ import ( const NameBody = "body" const NameId = "id" const NameTitle = "title" -const NameBodyCh = "bodyCh" -const NameTitleCh = "titleCh" +const NameBodyZh = "bodyCh" +const NameTitleZh = "titleCh" const limit = 40 const minGram = 2 @@ -51,7 +51,14 @@ func Test(t *testing.T) { err = tc.AddAndConsumeDocuments(doc) require.NoError(t, err) - result, err := tc.Search("body", 100, true, NameBody) + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("body"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameBody). + Build() + + result, err := tc.Search(sCtx) require.NoError(t, err) size, err := result.GetSize() @@ -177,14 +184,26 @@ func Test(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(1), docs) - result, err := tc.Search("ย", 100, true, NameTitle) + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("ย"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameTitle). + Build() + result, err := tc.Search(sCtx) require.NoError(t, err) size, err := result.GetSize() defer result.Free() require.Equal(t, 0, int(size)) - result2, err := tc.Search("ย่", 100, true, NameTitle) + sCtx2 := tantivy_go.NewSearchContextBuilder(). + SetQuery("ย่"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameTitle). + Build() + result2, err := tc.Search(sCtx2) require.NoError(t, err) size2, err := result2.GetSize() @@ -217,28 +236,52 @@ func Test(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(1), docs) - result, err := tc.Search("Idées fête", 100, true, NameTitle) + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("Idées fête"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameTitle). + Build() + result, err := tc.Search(sCtx) require.NoError(t, err) size, err := result.GetSize() defer result.Free() require.Equal(t, 1, int(size)) - result2, err := tc.Search("idees fete", 100, true, NameTitle) + sCtx2 := tantivy_go.NewSearchContextBuilder(). + SetQuery("idees fete"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameTitle). + Build() + result2, err := tc.Search(sCtx2) require.NoError(t, err) size2, err := result2.GetSize() defer result2.Free() require.Equal(t, 1, int(size2)) - result3, err := tc.Search("straße", 100, true, NameBody) + sCtx3 := tantivy_go.NewSearchContextBuilder(). + SetQuery("straße"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameBody). + Build() + result3, err := tc.Search(sCtx3) require.NoError(t, err) size3, err := result3.GetSize() defer result3.Free() require.Equal(t, 1, int(size3)) - result4, err := tc.Search("strasse", 100, true, NameBody) + sCtx4 := tantivy_go.NewSearchContextBuilder(). + SetQuery("strasse"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameBody). + Build() + result4, err := tc.Search(sCtx4) require.NoError(t, err) size4, err := result4.GetSize() @@ -261,7 +304,13 @@ func Test(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(1), docs) - result, err := tc.Search("1", 100, true, NameId) + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("1"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameId). + Build() + result, err := tc.Search(sCtx) require.NoError(t, err) size, err := result.GetSize() @@ -285,7 +334,13 @@ func Test(t *testing.T) { err = tc.AddAndConsumeDocuments(doc) require.NoError(t, err) - result, err := tc.Search("create", 100, true, NameTitle) + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("create"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameTitle). + Build() + result, err := tc.Search(sCtx) require.NoError(t, err) size, err := result.GetSize() @@ -346,13 +401,77 @@ func Test(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(2), docs) - result, err := tc.Search("售货员", 100, true, NameBodyCh, NameTitleCh) + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("售货员"). + SetDocsLimit(100). + SetWithHighlights(true). + AddFieldDefaultWeight(NameBodyZh). + AddFieldDefaultWeight(NameTitleZh). + Build() + result, err := tc.Search(sCtx) require.NoError(t, err) size, err := result.GetSize() defer result.Free() require.Equal(t, 2, int(size)) }) + + t.Run("docs search - when weights apply", func(t *testing.T) { + schema, tc := fx(t, limit, 1, false) + + defer tc.Free() + + doc, err := addDoc(t, "an apple", "", "id1", tc) + require.NoError(t, err) + + doc2, err := addDoc(t, "", "an apple", "id2", tc) + require.NoError(t, err) + + err = tc.AddAndConsumeDocuments(doc, doc2) + require.NoError(t, err) + + docs, err := tc.NumDocs() + require.NoError(t, err) + require.Equal(t, uint64(2), docs) + + sCtx := tantivy_go.NewSearchContextBuilder(). + SetQuery("apple"). + SetDocsLimit(100). + SetWithHighlights(false). + AddField(NameTitle, 1.0). + AddField(NameBody, 1.0). + Build() + result, err := tc.Search(sCtx) + require.NoError(t, err) + + size, err := result.GetSize() + defer result.Free() + require.Equal(t, 2, int(size)) + resDoc, err := result.Get(0) + require.NoError(t, err) + jsonStr, err := resDoc.ToJson(schema, NameId) + require.NoError(t, err) + require.JSONEq(t, `{"highlights":[],"id":"id1","score":1.9676434993743896}`, jsonStr) + + sCtx2 := tantivy_go.NewSearchContextBuilder(). + SetQuery("apple"). + SetDocsLimit(100). + SetWithHighlights(false). + AddField(NameTitle, 1.0). + AddField(NameBody, 10.0). + Build() + result2, err := tc.Search(sCtx2) + require.NoError(t, err) + + size2, err := result2.GetSize() + defer result2.Free() + require.Equal(t, 2, int(size2)) + resDoc2, err := result2.Get(0) + require.NoError(t, err) + jsonStr2, err := resDoc2.ToJson(schema, NameId) + require.NoError(t, err) + require.JSONEq(t, `{"highlights":[],"id":"id2","score":4.919108867645264}`, jsonStr2) + }) } func addDoc( @@ -367,7 +486,7 @@ func addDoc( err := doc.AddField(NameTitle, title, tc) require.NoError(t, err) - err = doc.AddField(NameTitleCh, title, tc) + err = doc.AddField(NameTitleZh, title, tc) require.NoError(t, err) err = doc.AddField(NameId, id, tc) @@ -376,7 +495,7 @@ func addDoc( err = doc.AddField(NameBody, body, tc) require.NoError(t, err) - err = doc.AddField(NameBodyCh, body, tc) + err = doc.AddField(NameBodyZh, body, tc) return doc, err } @@ -402,7 +521,7 @@ func fx( require.NoError(t, err) err = builder.AddTextField( - NameTitleCh, + NameTitleZh, true, true, false, @@ -432,7 +551,7 @@ func fx( require.NoError(t, err) err = builder.AddTextField( - NameBodyCh, + NameBodyZh, true, true, false, diff --git a/tantivycontext.go b/tantivycontext.go index 42c4a72..230cbc7 100644 --- a/tantivycontext.go +++ b/tantivycontext.go @@ -112,16 +112,14 @@ func (tc *TantivyContext) NumDocs() (uint64, error) { // Search performs a search query on the index and returns the search results. // // Parameters: -// - query (string): The search query string. -// - docsLimit (uintptr): The maximum number of documents to return. -// - withHighlights (bool): Whether to include highlights in the results. -// - fieldNames (...string): The names of the fields to be included in the search. +// - sCtx (SearchContext): The context for the search, containing query string, +// document limit, highlight option, and field weights. // // Returns: // - *SearchResult: A pointer to the SearchResult containing the search results. // - error: An error if the search fails. func (tc *TantivyContext) Search(sCtx SearchContext) (*SearchResult, error) { - fieldNames, weights := sCtx.GetFieldWeights() + fieldNames, weights := sCtx.GetFieldAndWeights() if len(fieldNames) == 0 { return nil, fmt.Errorf("fieldNames must not be empty") }