Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search performance/speed question on negative query #1828

Open
thoriqsatriya opened this issue May 29, 2023 · 0 comments
Open

Search performance/speed question on negative query #1828

thoriqsatriya opened this issue May 29, 2023 · 0 comments

Comments

@thoriqsatriya
Copy link

thoriqsatriya commented May 29, 2023

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:

  1. 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
  2. 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
  3. 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)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant