Skip to content
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

[Feature] Basic Filtering Options #109

Closed
CyanRook opened this issue Sep 6, 2019 · 6 comments
Closed

[Feature] Basic Filtering Options #109

CyanRook opened this issue Sep 6, 2019 · 6 comments

Comments

@CyanRook
Copy link
Contributor

CyanRook commented Sep 6, 2019

Premise

VTQuery provides a way to search inside a Vector Tile but doesn't provide a way to filter out results. This feature request is to implement a basic filtering mechanism to return only results that match the filters.

Desired Capability

As part of the options parameter sent to VTQuery, an additional feature can be included labelled filters. filters will contain an array of filter objects which consist of a parameter, condition, and value. Each result returned by VTQuery will satisfy all filters.

  • parameter - This will be the key inside parameters which the filter will be applied to
  • condition - Basic filter options <, <=, >, >=, =, !=
  • value - A value for which the features parameter will be compared.

Example

filters: [ {'parameter': 'size', 'condition': '>', 'value': 50}] will cause VTQuery to return only features with a size greater than 50.

To Be Determined

  • Should a condition contains be implemented for strings?
    • This would enable "City StoreName" to be returned on a query of contains StoreName
@mapsam
Copy link
Contributor

mapsam commented Sep 11, 2019

@CyanRook this looks great! I think I like your proposed API. Some alternatives, just for the sake of brainstorming:

// current proposal
{'parameter': 'size', 'condition': '>', 'value': 50}

// filter array
[ 'size', '>', 50 ]

// expression array
[ ">", [ "get", "size" ], "50" ]

I'm partial to the object and array formats for the sake of readability + simplicity.

I see that you're allowing multiple filter objects, are these AND operators or OR operators? If we go with multiple filters, it makes sense to make this option a full expression, which has this functionality described already. For example we can use the any operator:

[
  "all",
  [ ">", [ "get", "size" ], "50" ],
  [ "<", [ "get", "size" ], "100" ]
]

Implementing expressions is a long-haul option, though. Something more custom that allows us to implement AND/OR operators:

{
  "filter_operator": "AND",
  "filter": [ <filter1>, <filter2>, <filterN> ]
}

Basic filter options <, <=, >, >=, =, !=

👍 sounds great

Should a condition contains be implemented for strings?

probably, but not a deal-breaker for the first implementation of this feature, I think.

@CyanRook
Copy link
Contributor Author

I'm not 100% sure what [ "<", [ "get", "size" ], "100" ] would implement. Would that be querying on both get and size having them be less than 100?

@mapsam
Copy link
Contributor

mapsam commented Sep 18, 2019

@CyanRook this is the same thing as size < 100, but in expression format, which is more-or-less becoming the defacto Mapbox way of describing filters (in the Styles + Tilesets APIs). I think we shouldn't worry about implementing these yet, as there is no common C++ expression parsing library available without writing our own or requiring mapbox-gl-native in vtquery's build steps.

By the looks of the filter_feature implementation in #110 multiple filters denotes an AND operator. I'm happy to leave this as-is for now, and ticketing out the addition of an OR operator syntax.

@CyanRook
Copy link
Contributor Author

I think it would be easy enough to implement this format for some basic combinations starting with and and or. We can also limit this to a single depth for this implementation, so while it's easy to see how one could nest filters, we might not allow it yet depending on complexity. The keyword for query could also change from filter: to basic-filter: to differentiate and allow for expression formats in the future under either expression-filter or just plain filter.

Proposed new format:

[
  "and", // Combination operation accepting 'and' and 'or'
  ["size", ">", 50 ], // Filter operation accepting a keyword, comparator, and numeric value.
  ["size", "<", 100 ]
]

@CyanRook
Copy link
Contributor Author

Alternatively, do

[
  "all",
  [ ">", [ "get", "size" ], "50" ],
  [ "<", [ "get", "size" ], "100" ]
]

But without an actual expression engine behind it and error out if anyone tries to do anything outside this specific pattern.

@CyanRook
Copy link
Contributor Author

CyanRook commented Sep 24, 2019

The final format that was merged is

[
  "and", // Combination operation accepting 'and' and 'or'
  [
    ["size", ">", 50 ], // Filter operation accepting a keyword, comparator, and numeric value.
    ["size", "<", 100 ]
  ]
]

This example filter will return features which have 50 < 'size' < 100.

Supported combination operation types are 'and' and 'or'
Supported operations for numeric types are '=', '!=', '<', '<=', '>', and '>='.
Supported operations for boolean types are '=' and '!='
Strings are not supported.

@mapsam mapsam mentioned this issue Sep 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants