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

Add query parameter to filter results by name #15

Merged
merged 4 commits into from Sep 7, 2017

Conversation

Projects
None yet
2 participants
@c-w
Copy link
Member

commented Sep 6, 2017

What's this?

This pull request adds an additional query parameter called filter_name that lets users subsample the return values of the featureService to only those features whose name (partially) matches the provided string.

This is generally useful, e.g. imagine querying for all features in a bounding box or at a particular point but while already having an idea of the names of features that we want to retrieve. Additionally, the feature will be used in the Fortis dashboard for implementing auto-suggest in the place search pane.

Sample usage

Bounding box query without name filter: 32 results
image

Narrowing to just features matching "somali": 3 results
image

Try it live!

Implementation notes

We use the Postgres strpos function instead of a wildcard LIKE as it usually leads to better query plans for substring queries. For example, the below query plans show that strpos is a good 10% faster at execution and 40x faster at planning than the equivalent wildcard LIKE.

features=# explain analyze select name from features where strpos(lower(name),'aris')>0 limit 2;
                                                    QUERY PLAN
------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..1.20 rows=2 width=11) (actual time=0.044..3.088 rows=2 loops=1)
   ->  Seq Scan on features  (cost=0.00..94295.52 rows=157781 width=11) (actual time=0.043..3.087 rows=2 loops=1)
         Filter: (strpos(lower((name)::text), 'aris'::text) > 0)
         Rows Removed by Filter: 2538
 Planning time: 0.055 ms
 Execution time: 3.107 ms
(6 rows)

features=# explain analyze select name from features where lower(name) like '%aris%' limit 2;
                                                  QUERY PLAN
--------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..4048.35 rows=2 width=11) (actual time=0.051..3.454 rows=2 loops=1)
   ->  Seq Scan on features  (cost=0.00..93112.16 rows=46 width=11) (actual time=0.051..3.454 rows=2 loops=1)
         Filter: (lower((name)::text) ~~ '%aris%'::text)
         Rows Removed by Filter: 2139
 Planning time: 0.260 ms
 Execution time: 3.472 ms
(6 rows)

c-w added some commits Sep 6, 2017

Make binding of AND after OR explicit
We first want to do a disjunctive query on all names and then add any
potential additional filters as a joint conjunction at the end of that.
Add option to filter any query by name
This is generally useful, e.g. imagine querying for all features in a
bounding box or at a particular point but while already having an idea
of the names of features that we want to retrieve. Additionally, the
feature will be used in the Fortis dashboard for implementing
auto-suggest in the place search pane.

@c-w c-w requested review from timfpark and erikschlegel Sep 6, 2017

@c-w c-w self-assigned this Sep 6, 2017

@jcjimenez
Copy link
Contributor

left a comment

LGTM

@c-w c-w merged commit d9b4909 into master Sep 7, 2017

@c-w c-w deleted the filter-by-name branch Sep 7, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.