Created
February 21, 2017 08:59
-
-
Save korjavin/afe35d11165bbf916e279158c55e7537 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"github.com/tidwall/buntdb" | |
"github.com/tidwall/gjson" | |
"log" | |
"strconv" | |
) | |
type Order struct { | |
Oid int | |
Statuses []Orderstatus | |
} | |
type Orderstatus struct { | |
Sid int | |
Description string | |
} | |
func main() { | |
o1 := Order{Oid: 1, Statuses: []Orderstatus{Orderstatus{Sid: 1, Description: "Isn't relevant"}, Orderstatus{Sid: 2, Description: "Skip that"}}} | |
o2 := Order{Oid: 2, Statuses: []Orderstatus{Orderstatus{Sid: 1, Description: "Isn't relevant"}, Orderstatus{Sid: 6, Description: "This one"}}} | |
db, _ := buntdb.Open(":memory:") | |
buf1, _ := json.Marshal(o1) | |
buf2, _ := json.Marshal(o2) | |
db.Update(func(tx *buntdb.Tx) error { | |
_, _, err := tx.Set(strconv.Itoa(o1.Oid), string(buf1), nil) | |
_, _, err = tx.Set(strconv.Itoa(o2.Oid), string(buf2), nil) | |
return err | |
}) | |
db.Update(func(tx *buntdb.Tx) error { | |
err := tx.CreateIndex("sid", "*", buntdb.IndexJSON("Statuses.Sid")) | |
return err | |
}) | |
db.View(func(tx *buntdb.Tx) error { | |
tx.AscendGreaterOrEqual("sid", `{"Statuses.Sid":6}`, func(key, value string) bool { | |
var order Order | |
json.Unmarshal([]byte(value), &order) | |
name := gjson.Get(value, `Statuses.#[Sid=6].Description`) | |
log.Printf("value=%s,key=%s, sid=%s\n", value, key, name) | |
return true | |
}) | |
return nil | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
AFAIK it's not possible to index on a JSON array efficiently, such as the
Statuses
element.In your code the index is looking for an object at the path
Statuses.Sid
, but your JSON schema does not contain that path.buf1
andbuf2
become:When you enter one of the payloads into http://tidwall.com/gjson-play and use
Statuses.Sid
as the path you will see that result isnull
.So you have a couple options.
Do a full scan
If you don't have a ton of items, you can scan the entire dataset like such:
Create a many to many index
if you do have a lot of items then I recommend that you insert each
Sid/Oid
pair individually.It's more code an operations, but it will be very fast when querying.
Create an index only on the
oid_sid:
keys, known that each will have exactly oneOid
and oneSid
.Finally search for the
Sid
. This query will find allOid
s that contain an Orderstatus with aSid
of 6.This is what I came up with from a cursory look and I haven't tested the code.