diff --git a/go.mod b/go.mod index cdd6d812..4f571a54 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/tidwall/assert v0.1.0 github.com/tidwall/btree v1.4.4 github.com/tidwall/buntdb v1.2.9 - github.com/tidwall/geojson v1.3.6 + github.com/tidwall/geojson v1.4.0 github.com/tidwall/gjson v1.14.3 github.com/tidwall/hashmap v1.6.1 github.com/tidwall/limiter v0.4.0 diff --git a/go.sum b/go.sum index 2c0705b3..8b5f9906 100644 --- a/go.sum +++ b/go.sum @@ -359,8 +359,8 @@ github.com/tidwall/cities v0.1.0/go.mod h1:lV/HDp2gCcRcHJWqgt6Di54GiDrTZwh1aG2ZU github.com/tidwall/geoindex v1.4.4/go.mod h1:rvVVNEFfkJVWGUdEfU8QaoOg/9zFX0h9ofWzA60mz1I= github.com/tidwall/geoindex v1.7.0 h1:jtk41sfgwIt8MEDyC3xyKSj75iXXf6rjReJGDNPtR5o= github.com/tidwall/geoindex v1.7.0/go.mod h1:rvVVNEFfkJVWGUdEfU8QaoOg/9zFX0h9ofWzA60mz1I= -github.com/tidwall/geojson v1.3.6 h1:ZbpDNwdhXyDe8XGTplGVaGrcS2ViFaSoo3QBNXe1uhM= -github.com/tidwall/geojson v1.3.6/go.mod h1:1cn3UWfSYCJOq53NZoQ9rirdw89+DM0vw+ZOAVvuReg= +github.com/tidwall/geojson v1.4.0 h1:zsSlTU+6LVycCqiTVIpb2T9+ia6LvY05D+faSEXXWtI= +github.com/tidwall/geojson v1.4.0/go.mod h1:1cn3UWfSYCJOq53NZoQ9rirdw89+DM0vw+ZOAVvuReg= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/internal/collection/string.go b/internal/collection/string.go index 672ba079..2599d704 100644 --- a/internal/collection/string.go +++ b/internal/collection/string.go @@ -71,3 +71,7 @@ func (s String) NumPoints() int { func (s String) Distance(obj geojson.Object) float64 { return 0 } + +func (s String) Members() string { + return "" +} diff --git a/internal/server/scanner.go b/internal/server/scanner.go index 74c67d8a..ea5d3377 100644 --- a/internal/server/scanner.go +++ b/internal/server/scanner.go @@ -5,10 +5,12 @@ import ( "errors" "math" "strconv" + "strings" "github.com/mmcloughlin/geohash" "github.com/tidwall/btree" "github.com/tidwall/geojson" + "github.com/tidwall/gjson" "github.com/tidwall/resp" "github.com/tidwall/tile38/internal/clip" "github.com/tidwall/tile38/internal/collection" @@ -200,7 +202,24 @@ func extractZCoordinate(o geojson.Object) float64 { } } +func isPathKey(s string, key string) bool { + return strings.HasPrefix(s, key) && (s == key || s[len(key)] == '.') +} + func getFieldValue(o *object.Object, name string) field.Value { + if isPathKey(name, "properties") { + if g := o.Geo(); g != nil { + if res := gjson.Get(g.Members(), "properties"); res.Exists() { + if name != "properties" { + // We have a dot path suffix. + res = res.Get(name[len("properties")+1:]) + } + if res.Exists() { + return field.ValueOf(res.Raw) + } + } + } + } if name == "z" { z := extractZCoordinate(o.Geo()) return field.ValueOf(strconv.FormatFloat(z, 'f', -1, 64)) diff --git a/tests/keys_test.go b/tests/keys_test.go index 95c86d5c..518d2af0 100644 --- a/tests/keys_test.go +++ b/tests/keys_test.go @@ -475,6 +475,11 @@ func keys_FIELDS_test(mc *mockServer) error { Do("SCAN", "fleet", "WHERE", "hello.world", "<=", `tom`, "IDS").JSON().Str(`{"ok":true,"ids":["truck1","truck2"],"count":2,"cursor":0}`), Do("SCAN", "fleet", "WHERE", "hello.world", "<", `uom`, "IDS").JSON().Str(`{"ok":true,"ids":["truck1","truck2"],"count":2,"cursor":0}`), Do("SCAN", "fleet", "WHERE", "hello.world", "!=", `tom`, "IDS").JSON().Str(`{"ok":true,"ids":["truck1"],"count":1,"cursor":0}`), + + Do("SET", "fleet", "truck1", "OBJECT", `{"type":"Feature","geometry":{"type":"Point","coordinates":[-112,33]},"properties":{"speed":50},"asdf":"Adsf"}`).JSON().OK(), + Do("SCAN", "fleet", "WHERE", "properties.speed", ">", 49, "IDS").JSON().Str(`{"ok":true,"ids":["truck1"],"count":1,"cursor":0}`), + Do("SCAN", "fleet", "WHERE", "properties.speed", ">", 50, "IDS").JSON().Str(`{"ok":true,"ids":[],"count":0,"cursor":0}`), + Do("SCAN", "fleet", "WHERE", "properties.speed", "<", 51, "IDS").JSON().Str(`{"ok":true,"ids":["truck1","truck2"],"count":2,"cursor":0}`), ) }