From 066fbb790199c65a5d1336c277958d89d5f847f6 Mon Sep 17 00:00:00 2001 From: Josh Baker Date: Fri, 19 Aug 2016 11:56:43 -0700 Subject: [PATCH] descending indexes --- README.md | 58 +++++++++++++++++++++++++++++--------------------- buntdb.go | 7 ++++++ buntdb_test.go | 29 +++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c4ce5ff..3e156aa 100644 --- a/README.md +++ b/README.md @@ -419,34 +419,44 @@ This is similar to a [multi column index](http://dev.mysql.com/doc/refman/5.7/en In this example we are creating a multi value index on "name.last" and "age": ```go - db, _ := buntdb.Open(":memory:") - db.CreateIndex("last_name_age", "*", buntdb.IndexJSON("name.last"), buntdb.IndexJSON("age")) - db.Update(func(tx *buntdb.Tx) error { - tx.Set("1", `{"name":{"first":"Tom","last":"Johnson"},"age":38}`, nil) - tx.Set("2", `{"name":{"first":"Janet","last":"Prichard"},"age":47}`, nil) - tx.Set("3", `{"name":{"first":"Carol","last":"Anderson"},"age":52}`, nil) - tx.Set("4", `{"name":{"first":"Alan","last":"Cooper"},"age":28}`, nil) - tx.Set("5", `{"name":{"first":"Sam","last":"Anderson"},"age":51}`, nil) - tx.Set("6", `{"name":{"first":"Melinda","last":"Prichard"},"age":44}`, nil) - return nil - }) - db.View(func(tx *buntdb.Tx) error { - tx.Ascend("last_name_age", func(key, value string) bool { - fmt.Printf("%s: %s\n", key, value) - return true - }) - return nil +db, _ := buntdb.Open(":memory:") +db.CreateIndex("last_name_age", "*", buntdb.IndexJSON("name.last"), buntdb.IndexJSON("age")) +db.Update(func(tx *buntdb.Tx) error { + tx.Set("1", `{"name":{"first":"Tom","last":"Johnson"},"age":38}`, nil) + tx.Set("2", `{"name":{"first":"Janet","last":"Prichard"},"age":47}`, nil) + tx.Set("3", `{"name":{"first":"Carol","last":"Anderson"},"age":52}`, nil) + tx.Set("4", `{"name":{"first":"Alan","last":"Cooper"},"age":28}`, nil) + tx.Set("5", `{"name":{"first":"Sam","last":"Anderson"},"age":51}`, nil) + tx.Set("6", `{"name":{"first":"Melinda","last":"Prichard"},"age":44}`, nil) + return nil +}) +db.View(func(tx *buntdb.Tx) error { + tx.Ascend("last_name_age", func(key, value string) bool { + fmt.Printf("%s: %s\n", key, value) + return true }) + return nil +}) - // Output: - // 5: {"name":{"first":"Sam","last":"Anderson"},"age":51} - // 3: {"name":{"first":"Carol","last":"Anderson"},"age":52} - // 4: {"name":{"first":"Alan","last":"Cooper"},"age":28} - // 1: {"name":{"first":"Tom","last":"Johnson"},"age":38} - // 6: {"name":{"first":"Melinda","last":"Prichard"},"age":44} - // 2: {"name":{"first":"Janet","last":"Prichard"},"age":47} +// Output: +// 5: {"name":{"first":"Sam","last":"Anderson"},"age":51} +// 3: {"name":{"first":"Carol","last":"Anderson"},"age":52} +// 4: {"name":{"first":"Alan","last":"Cooper"},"age":28} +// 1: {"name":{"first":"Tom","last":"Johnson"},"age":38} +// 6: {"name":{"first":"Melinda","last":"Prichard"},"age":44} +// 2: {"name":{"first":"Janet","last":"Prichard"},"age":47} ``` +## Descending Ordered Index +Any index can be put in descending order by wrapping it's less function with `buntdb.Desc`. + +```go +db.CreateIndex("last_name_age", "*", + buntdb.IndexJSON("name.last"), + buntdb.Desc(buntdb.IndexJSON("age"))) +``` + +This will create a multi value index where the last name is ascending and the age is descending. ## Data Expiration Items can be automatically evicted by using the `SetOptions` object in the `Set` function to set a `TTL`. diff --git a/buntdb.go b/buntdb.go index 21f8b7c..c4a5de5 100644 --- a/buntdb.go +++ b/buntdb.go @@ -1612,3 +1612,10 @@ func IndexJSONCaseSensitive(path string) func(a, b string) bool { return gjson.Get(a, path).Less(gjson.Get(b, path), true) } } + +// Desc is a helper function that changes the order of an index. +func Desc(less func(a, b string) bool) func(a, b string) bool { + return func(a, b string) bool { + return less(b, a) + } +} diff --git a/buntdb_test.go b/buntdb_test.go index 4e84692..8e05d83 100644 --- a/buntdb_test.go +++ b/buntdb_test.go @@ -413,6 +413,35 @@ func TestVariousTx(t *testing.T) { t.Fatalf("should not be able to perform transactionso on a closed database.") } } +func ExampleDesc() { + db, _ := Open(":memory:") + db.CreateIndex("last_name_age", "*", IndexJSON("name.last"), Desc(IndexJSON("age"))) + db.Update(func(tx *Tx) error { + tx.Set("1", `{"name":{"first":"Tom","last":"Johnson"},"age":38}`, nil) + tx.Set("2", `{"name":{"first":"Janet","last":"Prichard"},"age":47}`, nil) + tx.Set("3", `{"name":{"first":"Carol","last":"Anderson"},"age":52}`, nil) + tx.Set("4", `{"name":{"first":"Alan","last":"Cooper"},"age":28}`, nil) + tx.Set("5", `{"name":{"first":"Sam","last":"Anderson"},"age":51}`, nil) + tx.Set("6", `{"name":{"first":"Melinda","last":"Prichard"},"age":44}`, nil) + return nil + }) + db.View(func(tx *Tx) error { + tx.Ascend("last_name_age", func(key, value string) bool { + fmt.Printf("%s: %s\n", key, value) + return true + }) + return nil + }) + + // Output: + //3: {"name":{"first":"Carol","last":"Anderson"},"age":52} + //5: {"name":{"first":"Sam","last":"Anderson"},"age":51} + //4: {"name":{"first":"Alan","last":"Cooper"},"age":28} + //1: {"name":{"first":"Tom","last":"Johnson"},"age":38} + //2: {"name":{"first":"Janet","last":"Prichard"},"age":47} + //6: {"name":{"first":"Melinda","last":"Prichard"},"age":44} +} + func ExampleDB_CreateIndex_jSON() { db, _ := Open(":memory:") db.CreateIndex("last_name", "*", IndexJSON("name.last"))