timshannon / badgerhold

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

Nested indexes are not supported? #59

Closed anxuanzi closed 3 years ago

anxuanzi commented 3 years ago

Hi, I was trying to use badgerhold in my project. I got a problem when I was trying to find a record. It said, "Nested indexes are not supported. Only top level structures can be indexed". I not so sure what I did wrong, or maybe I misunderstand the 'index' feature. If, I did anything wrong, please help me out to understand the index feature. Thank you!

Data struct:

type AdminUser struct {
    Username  string `json:"username" badgerhold:"key"`
    NickName  string `json:"nick_name"`
    FirstName string `json:"first_name"`
    LastName  string `json:"last_name"`
    Email     string `json:"email" badgerhold:"unique"`
    AvatarUrl string `json:"avatar_url"`
    Password  string `json:"password"`
    Authorities    string `json:"authorities"`
    CreateTime     int64  `json:"create_time"`
    LastModifyTime int64  `json:"last_modify_time"`
    LastLoginTime  int64  `json:"last_login_time"`
    StorageScope string `badgerhold:"index"`
}

Code for inserting data:

adminUser := &store.AdminUser{
        Username:        "abcd",
        NickName:        "aaa",
        FirstName:       "a",
        LastName:        "b",
        Email:           "a@example.com",
        Password:        "12345",
        Authorities:     "super",
        StorageScope: "admin.user",
}
err := app.Store.Insert("abcd", adminUser)

Code for finding record:

dbResult := &store.AdminUser{}
err := app.Store.FindOne(dbResult, badgerhold.Where("Username").Eq("abcd").Index("admin.user"))

Error message: panic: Nested indexes are not supported. Only top level structures can be indexed

Some additional information:

github.com/dgraph-io/badger/v3 v3.2011.1
github.com/timshannon/badgerhold/v3 v3.0.0-20210415132401-e7c90fb5919f

GOVERSION="go1.16.3"

OS: Manjaro Linux x86_64
Kernel: 5.12.1-2-MANJARO
timshannon commented 3 years ago

The name of the field is "StorageScope" not "admin.user". The Index query method doesn't actually do a criteria check. It's a hint telling the query planner what index to use.

You probably want a query like this:

err := app.Store.FindOne(dbResult, badgerhold.Where("Username").Eq("abcd").And("StorageScope").Eq("admin.user").Index("StorageScope"))
anxuanzi commented 3 years ago

Thank you so much! Now I understood what the index is for.