diff --git a/src/main/java/de/komoot/photon/elasticsearch/OsmTagFilter.java b/src/main/java/de/komoot/photon/elasticsearch/OsmTagFilter.java new file mode 100644 index 00000000..29d442b3 --- /dev/null +++ b/src/main/java/de/komoot/photon/elasticsearch/OsmTagFilter.java @@ -0,0 +1,74 @@ +package de.komoot.photon.elasticsearch; + +import java.util.List; + +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; + +import de.komoot.photon.searcher.TagFilter; +import de.komoot.photon.searcher.TagFilterKind; + +public class OsmTagFilter { + private BoolQueryBuilder orQueryBuilderForIncludeTagFiltering = null; + private BoolQueryBuilder andQueryBuilderForExcludeTagFiltering = null; + + public OsmTagFilter withOsmTagFilters(List filters) { + for (TagFilter filter : filters) { + addOsmTagFilter(filter); + } + return this; + } + + public BoolQueryBuilder getTagFiltersQuery() { + if (orQueryBuilderForIncludeTagFiltering != null || andQueryBuilderForExcludeTagFiltering != null) { + BoolQueryBuilder tagFilters = QueryBuilders.boolQuery(); + if (orQueryBuilderForIncludeTagFiltering != null) + tagFilters.must(orQueryBuilderForIncludeTagFiltering); + if (andQueryBuilderForExcludeTagFiltering != null) + tagFilters.mustNot(andQueryBuilderForExcludeTagFiltering); + return tagFilters; + } + return null; + } + + private OsmTagFilter addOsmTagFilter(TagFilter filter) { + if (filter.getKind() == TagFilterKind.EXCLUDE_VALUE) { + appendIncludeTermQuery(QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery("osm_key", filter.getKey())) + .mustNot(QueryBuilders.termQuery("osm_value", filter.getValue()))); + } else { + QueryBuilder builder; + if (filter.isKeyOnly()) { + builder = QueryBuilders.termQuery("osm_key", filter.getKey()); + } else if (filter.isValueOnly()) { + builder = QueryBuilders.termQuery("osm_value", filter.getValue()); + } else { + builder = QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery("osm_key", filter.getKey())) + .must(QueryBuilders.termQuery("osm_value", filter.getValue())); + } + if (filter.getKind() == TagFilterKind.INCLUDE) { + appendIncludeTermQuery(builder); + } else { + appendExcludeTermQuery(builder); + } + } + return this; + } + + private void appendIncludeTermQuery(QueryBuilder termQuery) { + if (orQueryBuilderForIncludeTagFiltering == null) + orQueryBuilderForIncludeTagFiltering = QueryBuilders.boolQuery(); + + orQueryBuilderForIncludeTagFiltering.should(termQuery); + } + + + private void appendExcludeTermQuery(QueryBuilder termQuery) { + if (andQueryBuilderForExcludeTagFiltering == null) + andQueryBuilderForExcludeTagFiltering = QueryBuilders.boolQuery(); + + andQueryBuilderForExcludeTagFiltering.should(termQuery); + } +} diff --git a/src/main/java/de/komoot/photon/elasticsearch/PhotonQueryBuilder.java b/src/main/java/de/komoot/photon/elasticsearch/PhotonQueryBuilder.java index 8a804f53..bf50b9c7 100644 --- a/src/main/java/de/komoot/photon/elasticsearch/PhotonQueryBuilder.java +++ b/src/main/java/de/komoot/photon/elasticsearch/PhotonQueryBuilder.java @@ -4,7 +4,6 @@ import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Point; import de.komoot.photon.searcher.TagFilter; -import de.komoot.photon.searcher.TagFilterKind; import org.elasticsearch.common.lucene.search.function.CombineFunction; import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery.ScoreMode; import org.elasticsearch.common.unit.Fuzziness; @@ -39,9 +38,7 @@ public class PhotonQueryBuilder { private State state; - private BoolQueryBuilder orQueryBuilderForIncludeTagFiltering = null; - - private BoolQueryBuilder andQueryBuilderForExcludeTagFiltering = null; + private OsmTagFilter osmTagFilter; private GeoBoundingBoxQueryBuilder bboxQueryBuilder; @@ -129,6 +126,8 @@ private PhotonQueryBuilder(String query, String language, String[] languages, bo .should(QueryBuilders.matchQuery("housenumber", query).analyzer("standard")) .should(QueryBuilders.existsQuery(String.format("name.%s.raw", language))); + osmTagFilter = new OsmTagFilter(); + state = State.PLAIN; } @@ -177,36 +176,8 @@ public PhotonQueryBuilder withBoundingBox(Envelope bbox) { } public PhotonQueryBuilder withOsmTagFilters(List filters) { - for (TagFilter filter : filters) { - addOsmTagFilter(filter); - } - return this; - } - - public PhotonQueryBuilder addOsmTagFilter(TagFilter filter) { state = State.FILTERED; - - if (filter.getKind() == TagFilterKind.EXCLUDE_VALUE) { - appendIncludeTermQuery(QueryBuilders.boolQuery() - .must(QueryBuilders.termQuery("osm_key", filter.getKey())) - .mustNot(QueryBuilders.termQuery("osm_value", filter.getValue()))); - } else { - QueryBuilder builder; - if (filter.isKeyOnly()) { - builder = QueryBuilders.termQuery("osm_key", filter.getKey()); - } else if (filter.isValueOnly()) { - builder = QueryBuilders.termQuery("osm_value", filter.getValue()); - } else { - builder = QueryBuilders.boolQuery() - .must(QueryBuilders.termQuery("osm_key", filter.getKey())) - .must(QueryBuilders.termQuery("osm_value", filter.getValue())); - } - if (filter.getKind() == TagFilterKind.INCLUDE) { - appendIncludeTermQuery(builder); - } else { - appendExcludeTermQuery(builder); - } - } + osmTagFilter.withOsmTagFilters(filters); return this; } @@ -219,7 +190,6 @@ public PhotonQueryBuilder withLayerFilters(Set filters) { } - /** * When this method is called, all filters are placed inside their containers and the top level filter * builder is built. Subsequent invocations of this method have no additional effect. Note that after this method @@ -230,12 +200,8 @@ public QueryBuilder buildQuery() { finalQueryBuilder = QueryBuilders.boolQuery().must(finalQueryWithoutTagFilterBuilder).filter(queryBuilderForTopLevelFilter); - if (state.equals(State.FILTERED)) { - BoolQueryBuilder tagFilters = QueryBuilders.boolQuery(); - if (orQueryBuilderForIncludeTagFiltering != null) - tagFilters.must(orQueryBuilderForIncludeTagFiltering); - if (andQueryBuilderForExcludeTagFiltering != null) - tagFilters.mustNot(andQueryBuilderForExcludeTagFiltering); + BoolQueryBuilder tagFilters = osmTagFilter.getTagFiltersQuery(); + if (state.equals(State.FILTERED) && tagFilters != null) { finalQueryBuilder.filter(tagFilters); } @@ -250,25 +216,6 @@ public QueryBuilder buildQuery() { return finalQueryBuilder; } - - private void appendIncludeTermQuery(QueryBuilder termQuery) { - - if (orQueryBuilderForIncludeTagFiltering == null) - orQueryBuilderForIncludeTagFiltering = QueryBuilders.boolQuery(); - - orQueryBuilderForIncludeTagFiltering.should(termQuery); - } - - - private void appendExcludeTermQuery(QueryBuilder termQuery) { - - if (andQueryBuilderForExcludeTagFiltering == null) - andQueryBuilderForExcludeTagFiltering = QueryBuilders.boolQuery(); - - andQueryBuilderForExcludeTagFiltering.should(termQuery); - } - - private enum State { PLAIN, FILTERED, QUERY_ALREADY_BUILT, FINISHED, } diff --git a/src/main/java/de/komoot/photon/elasticsearch/ReverseQueryBuilder.java b/src/main/java/de/komoot/photon/elasticsearch/ReverseQueryBuilder.java index e6a874eb..e183df5c 100644 --- a/src/main/java/de/komoot/photon/elasticsearch/ReverseQueryBuilder.java +++ b/src/main/java/de/komoot/photon/elasticsearch/ReverseQueryBuilder.java @@ -2,7 +2,6 @@ import com.vividsolutions.jts.geom.Point; import de.komoot.photon.searcher.TagFilter; -import de.komoot.photon.searcher.TagFilterKind; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; @@ -21,14 +20,14 @@ public class ReverseQueryBuilder { private String queryStringFilter; private Set layerFilter; - private BoolQueryBuilder orQueryBuilderForIncludeTagFiltering = null; - private BoolQueryBuilder andQueryBuilderForExcludeTagFiltering = null; + private OsmTagFilter osmTagFilter; private ReverseQueryBuilder(Point location, Double radius, String queryStringFilter, Set layerFilter) { this.location = location; this.radius = radius; this.queryStringFilter = queryStringFilter; this.layerFilter = layerFilter; + this.osmTagFilter = new OsmTagFilter(); } public static ReverseQueryBuilder builder(Point location, Double radius, String queryStringFilter, Set layerFilter) { @@ -48,12 +47,8 @@ public QueryBuilder buildQuery() { finalQuery.must(new TermsQueryBuilder("type", layerFilter)); } - if (orQueryBuilderForIncludeTagFiltering != null || andQueryBuilderForExcludeTagFiltering != null) { - BoolQueryBuilder tagFilters = QueryBuilders.boolQuery(); - if (orQueryBuilderForIncludeTagFiltering != null) - tagFilters.must(orQueryBuilderForIncludeTagFiltering); - if (andQueryBuilderForExcludeTagFiltering != null) - tagFilters.mustNot(andQueryBuilderForExcludeTagFiltering); + BoolQueryBuilder tagFilters = osmTagFilter.getTagFiltersQuery(); + if (tagFilters != null) { finalQuery.filter(tagFilters); } @@ -65,51 +60,7 @@ public QueryBuilder buildQuery() { } public ReverseQueryBuilder withOsmTagFilters(List filters) { - for (TagFilter filter : filters) { - addOsmTagFilter(filter); - } + osmTagFilter.withOsmTagFilters(filters); return this; } - - public ReverseQueryBuilder addOsmTagFilter(TagFilter filter) { - if (filter.getKind() == TagFilterKind.EXCLUDE_VALUE) { - appendIncludeTermQuery(QueryBuilders.boolQuery() - .must(QueryBuilders.termQuery("osm_key", filter.getKey())) - .mustNot(QueryBuilders.termQuery("osm_value", filter.getValue()))); - } else { - QueryBuilder builder; - if (filter.isKeyOnly()) { - builder = QueryBuilders.termQuery("osm_key", filter.getKey()); - } else if (filter.isValueOnly()) { - builder = QueryBuilders.termQuery("osm_value", filter.getValue()); - } else { - builder = QueryBuilders.boolQuery() - .must(QueryBuilders.termQuery("osm_key", filter.getKey())) - .must(QueryBuilders.termQuery("osm_value", filter.getValue())); - } - if (filter.getKind() == TagFilterKind.INCLUDE) { - appendIncludeTermQuery(builder); - } else { - appendExcludeTermQuery(builder); - } - } - return this; - } - - private void appendIncludeTermQuery(QueryBuilder termQuery) { - - if (orQueryBuilderForIncludeTagFiltering == null) - orQueryBuilderForIncludeTagFiltering = QueryBuilders.boolQuery(); - - orQueryBuilderForIncludeTagFiltering.should(termQuery); - } - - - private void appendExcludeTermQuery(QueryBuilder termQuery) { - - if (andQueryBuilderForExcludeTagFiltering == null) - andQueryBuilderForExcludeTagFiltering = QueryBuilders.boolQuery(); - - andQueryBuilderForExcludeTagFiltering.should(termQuery); - } }