-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Complex filters #407
Comments
Looks good! I'm seeing a couple possible issues orWith the suggested Instead we could do: {
"$or": [
{ "class": "motorway" },
{ "class": "motorway_link" } ] } and possibly have a $in operator to make this shorter {
"class": { "$in": [ "motorway", "motorway_link" ] }
} magic keywordsThe magic keywords source, layer and type aren't clearly special, and reserving them make it impossible for these words to be used as feature keys. type is currently used as a key in mapbox streets, and seems like something that would also be commonly used in custom data We could prefix them: The suggested filter format, especially with these changes, is very similar to mongodb's comparison and logical operators. Should we follow @tmcw's suggestion and just full adopt those? guide and list of comparison and logical operators The remaining differences are mostly renames. |
@ansis it would be an extension of the current syntax, so one field with multiple values is specified simply like this: "class": ["motorway", "motorway_link"] So if value is an array, it's an "or" relation. We could fully adopt the Mongo syntax, but it wouldn't look as compact I think, and we would be more limited in how we can customize it specifically for GL styles. |
We could also add some more syntactic sugar and allow multiple operators per field like this: "localrank": {">": 4, "<=": 16} |
"filter": { // "and" at the top level
"source": "outdoors",
"layer": "poi_label",
"scalerank": 4,
">": {"localrank": 4},
"<=": {"localrank": 16}
} is problematic because it'd make it impossible to select the attributes I think we should go with MongoDB's query syntax; it looks pretty concise. Instead of having the A modified MongoDB syntax would look like this: {
"scalerank": 4,
"localrank": { "<=": 16, ">": 4 }
} and the original MongoDB syntax is {
"scalerank": 4,
"localrank": { "$lte": 16, "$gt": 4 }
} |
I agree we can go with MongoDB-style, but with some more differences. E.g. I'm convinced we need to keep the current
Because it is a part of a filter semantically. Having it at the top of the layer object is confusing for users. |
I think what you're looking for is the $in query // currently
{ "field": ["foo", "bar"] }
// mongo
{ "field": { "$in": ["foo", "bar"] } } |
I think @mourner is proposing making |
Yes. I think we don't need exact array matching at all (although we can have a special operator for it), just checking that a field contains each of the multiple fields, e.g.: {"food": {"$has": ["restaurant", "chinese"]}} |
In #430 |
Forgot to mention one more reason: filter properties are inherited, so you can make styles more compact by combining layers with shared source, layer or feature_type into groups and specifying the property once for the whole group. |
Wait, we support nested sources that inherit from their parents? Is there an example for this? |
No example currently since migration scripts don't group layers — you have to do that manually if you want, but basically, lets say we have: {
"id": "landcover_snow",
"filter": {"source": "outdoors", "layer": "landcover", "class": "snow"}
}, {
"id": "landcover_crop",
"filter": {"source": "outdoors", "layer": "landcover", "class": "crop"}
}, {
"id": "landcover_grass",
"filter": {"source": "outdoors", "layer": "landcover", "class": "grass"}
}, {
"id": "landcover_scrub",
"filter": {"source": "outdoors", "layer": "landcover", "class": "scrub"}
}, {
"id": "landcover_wood",
"filter": {"source": "outdoors", "layer": "landcover", "class": "wood"}
} We can group them like this: {
"id": "landcover",
"filter": {"source": "outdoors", "layer": "landcover"},
"layers": [{
"id": "landcover_snow",
"filter": {"class": "snow"}
}, {
"id": "landcover_crop",
"filter": {"class": "crop"}
}, {
"id": "landcover_grass",
"filter": {"class": "grass"}
}, {
"id": "landcover_scrub",
"filter": {"class": "scrub"}
}, {
"id": "landcover_wood",
"filter": {"class": "wood"}
}]
} When preprocessing, the group filter gets propagated to children layers. |
How are we going to represent nested layers then? As I understand it, all of the |
Whenever styles indicate that the group will be composited, e.g. with opacity, prerender, comp-ops etc. Do you see any issues with this approach? |
All new events
Example from v0 style for native:
For the new style format, I suggest implementing the following syntax:
Nested filters would look like this:
Or with
&&
,||
,!
,=~
instead of$and
,$or
,$not
,$match
.It looks pretty clear, easy to read, and very compact for most cases. Consider that we're optimizing for common filters that are usually used in a style, not super-complex tree-like filters, because they are uncommon (but should still be possible).
@ansis @kkaefer @edenh @nickidlugash @incanus thoughts? Related discussions: #356
The text was updated successfully, but these errors were encountered: