-
Notifications
You must be signed in to change notification settings - Fork 697
Open
Description
Hi, I want to use bleve to search from slice of struct but I have performance issue.
I want to search exact match with one of the field, sometimes I need negative search and sometimes positive. I don't need to use full text search for this case. Here is what I found so far:
- Search using negative search will have much slower performance even when the result count is around the same? I would expect it to be the same because it returns same number of hits
- Search on struct with fewer field will have faster performance, compared when the struct has more field. I would expect it to be the same because I only search on one field. On SQL, it will be
select field from table, it should not have noticeable performance difference when the table has more field or not - How to disable full text search?
Anyone know what I'm doing wrong here? And how to achieve what I want? Thank you
Here is the result:
negative search on simplified struct: 7.718755ms
negative search on normal struct: 10.91501ms
positive search on simplified struct: 2.358683ms
positive search on normal struct: 2.237731ms
Here is my code:
package main
import (
"fmt"
"github.com/blevesearch/bleve/v2"
"github.com/google/uuid"
"math/rand"
"time"
)
type UserSimple struct {
Age int `json:"age"`
ID string `json:"id"`
Nationality string `json:"nationality"`
}
type User struct {
Age int `json:"age"`
ID string `json:"id"`
Nationality string `json:"nationality"`
Field string `json:"field"`
Field2 string `json:"field2"`
Field3 string `json:"field3"`
Field4 string `json:"field4"`
Field5 string `json:"field5"`
Field6 string `json:"field6"`
}
func main() {
mapping := bleve.NewIndexMapping()
index, err := bleve.NewMemOnly(mapping)
if err != nil {
panic(err)
}
defer func() { _ = index.Close() }()
index2, err := bleve.NewMemOnly(mapping)
if err != nil {
panic(err)
}
defer func() { _ = index2.Close() }()
for i := 0; i < 1000; i++ {
userID := uuid.NewString()
err = index.Index(userID, UserSimple{
Age: rand.Int(),
ID: userID,
Nationality: "US",
})
if err != nil {
panic(err)
}
err = index2.Index(userID, User{
Age: rand.Int(),
ID: userID,
Nationality: "US",
Field: userID,
Field2: userID,
Field3: userID,
Field4: userID,
Field5: userID,
Field6: userID,
})
if err != nil {
panic(err)
}
}
err = index.Index("test", UserSimple{
Age: 20,
ID: "test",
})
if err != nil {
panic(err)
}
err = index2.Index("test", User{
Age: 20,
ID: "test",
})
if err != nil {
panic(err)
}
n := 100
var totalDurNegativeStruct1 time.Duration
var totalDurNegativeStruct2 time.Duration
var totalDurPositiveStruct1 time.Duration
var totalDurPositiveStruct2 time.Duration
// iterate n times to find the average
for i := 0; i < n; i++ {
queryNegative := bleve.NewQueryStringQuery("-id:test")
searchNegative := bleve.NewSearchRequestOptions(queryNegative, 10, 0, false)
searchNegative.Size = 1000
queryPositive := bleve.NewQueryStringQuery("nationality:US")
searchPositive := bleve.NewSearchRequestOptions(queryPositive, 10, 0, false)
searchPositive.Size = 1000
resultNegative, errQuery := index.Search(searchNegative)
if errQuery != nil {
panic(errQuery)
}
totalDurNegativeStruct1 += resultNegative.Took
resultNegative2, errQuery := index2.Search(searchNegative)
if errQuery != nil {
panic(errQuery)
}
totalDurNegativeStruct2 += resultNegative2.Took
resultPositive, errQuery := index.Search(searchPositive)
if errQuery != nil {
panic(errQuery)
}
totalDurPositiveStruct1 += resultPositive.Took
resultPositive2, errQuery := index2.Search(searchPositive)
if errQuery != nil {
panic(errQuery)
}
totalDurPositiveStruct2 += resultPositive2.Took
}
fmt.Println(time.Duration(int64(totalDurNegativeStruct1) / int64(n)))
fmt.Println(time.Duration(int64(totalDurNegativeStruct2) / int64(n)))
fmt.Println(time.Duration(int64(totalDurPositiveStruct1) / int64(n)))
fmt.Println(time.Duration(int64(totalDurPositiveStruct2) / int64(n)))
}Metadata
Metadata
Assignees
Labels
No labels