mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-10-12 01:02:48 -04:00
test(search): pin the geo predicates in the parity suite
This commit is contained in:
1 parent
003323670b
commit
71b4f95172
6 files changed
+76
-3
No files matched your search
+13
-1
@@ -39,6 +39,16 @@ func (e UnsupportedTimeRangeError) Error() string {
|
||||
return fmt.Sprintf("unable to convert '%v' to a time range", e.Value)
|
||||
}
|
||||
|
||||
// GeoFieldError records a geo predicate that was used on a field that is not
|
||||
// indexed as a geopoint.
|
||||
type GeoFieldError struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
func (e GeoFieldError) Error() string {
|
||||
return fmt.Sprintf("geo predicate on non-geo field %q", e.Key)
|
||||
}
|
||||
|
||||
// IsValidationError reports whether err is one of the KQL parse/validation
|
||||
// errors produced by this package, i.e. the query itself is at fault and the
|
||||
// caller should treat it as a bad request.
|
||||
@@ -47,9 +57,11 @@ func IsValidationError(err error) bool {
|
||||
startsWithBinaryOperator *StartsWithBinaryOperatorError
|
||||
namedGroupInvalidNodes *NamedGroupInvalidNodesError
|
||||
unsupportedTimeRange *UnsupportedTimeRangeError
|
||||
geoField *GeoFieldError
|
||||
)
|
||||
|
||||
return errors.As(err, &startsWithBinaryOperator) ||
|
||||
errors.As(err, &namedGroupInvalidNodes) ||
|
||||
errors.As(err, &unsupportedTimeRange)
|
||||
errors.As(err, &unsupportedTimeRange) ||
|
||||
errors.As(err, &geoField)
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
func geoQueryField(key string) (string, error) {
|
||||
field, ok := query.ResolveGeoField(key)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("geo predicate on non-geo field %q", key)
|
||||
return "", &kql.GeoFieldError{Key: key}
|
||||
}
|
||||
return field, nil
|
||||
}
|
||||
|
||||
@@ -418,6 +418,26 @@ Fixtures:
|
||||
| RANGE-07 | `mtime>2021` | no match | no match | no match | ✅ |
|
||||
| RANGE-08 | `name>100` | no match | no match | no match | ✅ |
|
||||
|
||||
### geo
|
||||
|
||||
Fixtures:
|
||||
|
||||
- `vienna.txt`
|
||||
- `bruck.txt`
|
||||
- `berlin.txt`
|
||||
- `nowhere.txt`
|
||||
|
||||
| Case | Query | expected | bleve | OpenSearch | same? |
|
||||
|---|---|---|---|---|---|
|
||||
| GEO-01 | `location:geo.distance(48.2082, 16.3738, 5km)` | vienna.txt | vienna.txt | vienna.txt | ✅ |
|
||||
| GEO-02 | `location:geo.distance(48.2082, 16.3738, 50km)` | bruck.txt, vienna.txt | bruck.txt, vienna.txt | bruck.txt, vienna.txt | ✅ |
|
||||
| GEO-03 | `location:geo.distance(48.2082, 16.3738, 1m)` | vienna.txt | vienna.txt | vienna.txt | ✅ |
|
||||
| GEO-04 | `location:geo.bbox(47.9, 16.1, 48.3, 16.5)` | vienna.txt | vienna.txt | vienna.txt | ✅ |
|
||||
| GEO-05 | `location:geo.bbox(48.3, 16.1, 47.9, 16.5)` | vienna.txt | vienna.txt | vienna.txt | ✅ |
|
||||
| GEO-06 | `location:geo.polygon(48.3 16.1, 48.3 16.5, 47.9 16.5, 47.9 16.1)` | vienna.txt | vienna.txt | vienna.txt | ✅ |
|
||||
| GEO-07 | `location:geo.distance(0, 0, 20000km)` | berlin.txt, bruck.txt, vienna.txt | berlin.txt, bruck.txt, vienna.txt | berlin.txt, bruck.txt, vienna.txt | ✅ |
|
||||
| GEO-08 | `name:geo.distance(48.2082, 16.3738, 5km)` | bad request | bad request | bad request | ✅ |
|
||||
|
||||
### scope
|
||||
|
||||
Fixtures:
|
||||
|
||||
@@ -109,6 +109,7 @@ func queryGroups() []queryGroup {
|
||||
stressGroup(),
|
||||
everythingGroup(),
|
||||
rangeGroup(),
|
||||
geoGroup(),
|
||||
scopeGroup(),
|
||||
invalidGroup(),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package parity
|
||||
|
||||
import (
|
||||
libregraph "github.com/opencloud-eu/libre-graph-api-go"
|
||||
|
||||
"github.com/opencloud-eu/opencloud/services/search/pkg/search"
|
||||
)
|
||||
|
||||
func at(lat, lon float64) fixtureOption {
|
||||
return withLocation(&libregraph.GeoCoordinates{
|
||||
Latitude: libregraph.PtrFloat64(lat),
|
||||
Longitude: libregraph.PtrFloat64(lon),
|
||||
})
|
||||
}
|
||||
|
||||
func geoGroup() queryGroup {
|
||||
return queryGroup{
|
||||
name: "geo",
|
||||
fixtures: []search.Resource{
|
||||
// vienna, and a second point ~35km east of it
|
||||
fixtureDoc("vienna.txt", at(48.2082, 16.3738)),
|
||||
fixtureDoc("bruck.txt", at(48.2082, 16.8500)),
|
||||
fixtureDoc("berlin.txt", at(52.5200, 13.4050)),
|
||||
fixtureDoc("nowhere.txt"),
|
||||
},
|
||||
cases: []queryCase{
|
||||
{id: 1, query: `location:geo.distance(48.2082, 16.3738, 5km)`, want: []string{"vienna.txt"}},
|
||||
{id: 2, query: `location:geo.distance(48.2082, 16.3738, 50km)`, want: []string{"vienna.txt", "bruck.txt"}},
|
||||
{id: 3, query: `location:geo.distance(48.2082, 16.3738, 1m)`, want: []string{"vienna.txt"}},
|
||||
{id: 4, query: `location:geo.bbox(47.9, 16.1, 48.3, 16.5)`, want: []string{"vienna.txt"}},
|
||||
// the corners may come in either order, both name the same box
|
||||
{id: 5, query: `location:geo.bbox(48.3, 16.1, 47.9, 16.5)`, want: []string{"vienna.txt"}},
|
||||
{id: 6, query: `location:geo.polygon(48.3 16.1, 48.3 16.5, 47.9 16.5, 47.9 16.1)`, want: []string{"vienna.txt"}},
|
||||
// a document without a location is never a geo hit
|
||||
{id: 7, query: `location:geo.distance(0, 0, 20000km)`, want: []string{"vienna.txt", "bruck.txt", "berlin.txt"}},
|
||||
// geo predicates only apply to geopoint fields, both engines reject the rest
|
||||
{id: 8, query: `name:geo.distance(48.2082, 16.3738, 5km)`, wantBadRequest: true},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ var bleveEscaper = strings.NewReplacer(
|
||||
func geoQueryField(key string) (string, error) {
|
||||
field, ok := searchQuery.ResolveGeoField(key)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("geo predicate on non-geo field %q", key)
|
||||
return "", &kql.GeoFieldError{Key: key}
|
||||
}
|
||||
return field, nil
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user