timshannon / badgerhold

BadgerHold is an embeddable NoSQL store for querying Go types built on Badger
MIT License
514 stars 52 forks source link

HasSuffix filter does not work for keys #74

Closed egast closed 2 years ago

egast commented 2 years ago

Hi, I looks like filtering (string) keys by prefix (and suffix) does not work as expected. For example, when I have inserted items with keys prefixed with test I would expect that store.Find(&result, badgerhold.Where(badgerhold.Key).HasPrefix("test")) gives the inserted items but it finds nothing.

I have modified the example._test.go to reproduce the issue.

package main

import (
    "fmt"
    "log"
    "os"
    "time"

    "io/ioutil"

    "github.com/dgraph-io/badger/v3"
    "github.com/timshannon/badgerhold/v4"
)

type Item struct {
    ID       string
    Category string `badgerholdIndex:"Category"`
    Created  time.Time
}

func id(n int) string {
    return "test_" + fmt.Sprint(n)
}

func main() {
    data := []Item{
        {
            ID:       id(0),
            Category: "blue",
            Created:  time.Now().Add(-4 * time.Hour),
        },
        {
            ID:       id(1),
            Category: "red",
            Created:  time.Now().Add(-3 * time.Hour),
        },
        {
            ID:       id(2),
            Category: "blue",
            Created:  time.Now().Add(-2 * time.Hour),
        },
        {
            ID:       id(3),
            Category: "blue",
            Created:  time.Now().Add(-20 * time.Minute),
        },
    }

    dir := tempdir()
    defer os.RemoveAll(dir)

    options := badgerhold.DefaultOptions
    options.Dir = dir
    options.ValueDir = dir
    store, err := badgerhold.Open(options)
    defer store.Close()

    if err != nil {
        // handle error
        log.Fatal(err)
    }

    // insert the data in one transaction

    err = store.Badger().Update(func(tx *badger.Txn) error {
        for i := range data {
            err := store.TxInsert(tx, data[i].ID, data[i])
            if err != nil {
                return err
            }
        }
        return nil
    })

    if err != nil {
        // handle error
        log.Fatal(err)
    }

    // Find all items in the blue category that have been created in the past hour
    var result []Item

    err = store.Find(&result, badgerhold.Where(badgerhold.Key).HasPrefix("test"))

    if err != nil {
        // handle error
        log.Fatal(err)
    }

    fmt.Printf("This should be non-empty: %v", result)
    // Output: 3

}

// tempdir returns a temporary dir path.
func tempdir() string {
    name, err := ioutil.TempDir("", "badgerhold-")
    if err != nil {
        panic(err)
    }
    return name
}