From f02f676a6037b3b5e5c4d1a914e4d73485e57484 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Mon, 14 Jun 2021 14:45:06 +0200 Subject: [PATCH 1/3] cleanup type filter tests Factors out common code and reformats the tests to make them more readable. --- .../query/PhotonQueryBuilderSearchTest.java | 189 ++++++++++-------- 1 file changed, 103 insertions(+), 86 deletions(-) diff --git a/src/test/java/de/komoot/photon/query/PhotonQueryBuilderSearchTest.java b/src/test/java/de/komoot/photon/query/PhotonQueryBuilderSearchTest.java index 703bd6d9e..c8a16e6fc 100644 --- a/src/test/java/de/komoot/photon/query/PhotonQueryBuilderSearchTest.java +++ b/src/test/java/de/komoot/photon/query/PhotonQueryBuilderSearchTest.java @@ -1,41 +1,34 @@ package de.komoot.photon.query; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import de.komoot.photon.ESBaseTester; import de.komoot.photon.PhotonDoc; import de.komoot.photon.elasticsearch.Importer; import static org.junit.Assert.assertEquals; -import java.io.IOException; import java.util.Arrays; -import java.util.Set; +import java.util.Collections; +import de.komoot.photon.elasticsearch.PhotonIndex; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; -import org.elasticsearch.client.Client; import org.elasticsearch.index.query.QueryBuilder; import org.junit.Before; import org.junit.Test; -/** - * Created by Sachin Dole on 2/20/2015. - */ public class PhotonQueryBuilderSearchTest extends ESBaseTester { + private static final String[] TAGS = new String[]{"tourism", "attraction", "tourism", "hotel", "tourism", "museum", "tourism", "information", "amenity", + "parking", "amenity", "restaurant", "amenity", "information", "food", "information", "railway", "station"}; @Before public void setUp() throws Exception { setUpES(); - ImmutableList tags = ImmutableList.of("tourism", "attraction", "tourism", "hotel", "tourism", "museum", "tourism", "information", "amenity", - "parking", "amenity", "restaurant", "amenity", "information", "food", "information", "railway", "station"); Importer instance = makeImporter(); double lon = 13.38886; double lat = 52.51704; - for (int i = 0; i < tags.size(); i++) { - String key = tags.get(i); - String value = tags.get(++i); + for (int i = 0; i < TAGS.length; i++) { + String key = TAGS[i]; + String value = TAGS[++i]; PhotonDoc doc = this.createDoc(lon, lat, i, i, key, value); instance.add(doc); lon += 0.00004; @@ -49,19 +42,25 @@ public void setUp() throws Exception { refresh(); } + private PhotonQueryBuilder baseQueryBerlin() { + return PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true); + } + + private SearchResponse search(QueryBuilder queryBuilder) { + return getClient().prepareSearch(PhotonIndex.NAME).setSearchType(SearchType.QUERY_THEN_FETCH).setQuery(queryBuilder).execute().actionGet(); + } /** * Find me all places named "berlin" that are tagged "tourism=attraction" - * - * @throws IOException */ @Test - public void testFilterWithTagTourismAttraction() throws IOException { - Client client = getClient(); - Set valueSet = ImmutableSet.of("attraction"); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withTags(ImmutableMap.of("tourism", valueSet)); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testFilterWithTagTourismAttraction() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withTags(Collections.singletonMap("tourism", Collections.singleton("attraction"))) + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(2l, searchResponse.getHits().getTotalHits()); } @@ -69,11 +68,13 @@ public void testFilterWithTagTourismAttraction() throws IOException { * Find me all places named "berlin" that are tagged with a value of "attraction". */ @Test - public void testValueAttraction() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withValues("attraction"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testValueAttraction() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withValues("attraction") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(2l, searchResponse.getHits().getTotalHits()); } @@ -81,11 +82,13 @@ public void testValueAttraction() throws IOException { * Find me all places named "berlin" that are tagged with key "tourism". */ @Test - public void testKeyTourism() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withKeys("tourism"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testKeyTourism() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withKeys("tourism") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(8l, searchResponse.getHits().getTotalHits()); } @@ -93,36 +96,41 @@ public void testKeyTourism() throws IOException { * Find me all places named "berlin" that are NOT tagged "tourism=attraction" */ @Test - public void testFilterWithoutTagTourismAttraction() throws IOException { - Client client = getClient(); - Set valueSet = ImmutableSet.of("attraction"); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withoutTags(ImmutableMap.of("tourism", valueSet)); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testFilterWithoutTagTourismAttraction() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withoutTags(Collections.singletonMap("tourism", Collections.singleton("attraction"))) + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(16l, searchResponse.getHits().getTotalHits()); } /** - * Find me all places named "berlin" that do not have the value "information" in their tags - no matter what key + * Find me all places named "berlin" that do not have the value "information" in their TAGS - no matter what key */ @Test - public void testValueNotInformation() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withoutValues("information"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testValueNotInformation() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withoutValues("information") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(12l, searchResponse.getHits().getTotalHits()); } /** - * Find me all places named "berlin" that do not have the key "tourism" in their tags + * Find me all places named "berlin" that do not have the key "tourism" in their TAGS */ @Test - public void testKeyNotTourism() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withoutKeys("tourism"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testKeyNotTourism() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withoutKeys("tourism") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(10l, searchResponse.getHits().getTotalHits()); } @@ -133,11 +141,14 @@ public void testKeyNotTourism() throws IOException { * {@link PhotonQueryBuilderSearchTest#testKeyTourismButValueNotInformation()} */ @Test - public void testKeyTourismAndValueNotInformation() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withKeys("tourism").withoutValues("information"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testKeyTourismAndValueNotInformation() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withKeys("tourism") + .withoutValues("information") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(6l, searchResponse.getHits().getTotalHits()); } @@ -148,12 +159,13 @@ public void testKeyTourismAndValueNotInformation() throws IOException { * {@link PhotonQueryBuilderSearchTest#testKeyTourismAndValueNotInformation}. */ @Test - public void testKeyTourismButValueNotInformation() throws IOException { - Client client = getClient(); - Set valueSet = ImmutableSet.of("information"); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withTagsNotValues(ImmutableMap.of("tourism", valueSet)); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testKeyTourismButValueNotInformation() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withTagsNotValues(Collections.singletonMap("tourism", Collections.singleton("information"))) + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(6l, searchResponse.getHits().getTotalHits()); } @@ -161,11 +173,13 @@ public void testKeyTourismButValueNotInformation() throws IOException { * Find me all places named "berlin" that are tagged without the keys "tourism" and "amenity". */ @Test - public void testKeyNotTourismAndKeyNotAmenity() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withoutKeys("tourism", "amenity"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testKeyNotTourismAndKeyNotAmenity() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withoutKeys("tourism", "amenity") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(4l, searchResponse.getHits().getTotalHits()); } @@ -175,11 +189,14 @@ public void testKeyNotTourismAndKeyNotAmenity() throws IOException { * on "amenity" */ @Test - public void testKeyTourismAndKeyNotAmenity() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withKeys("tourism").withoutKeys("amenity"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testKeyTourismAndKeyNotAmenity() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withKeys("tourism") + .withoutKeys("amenity") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(8l, searchResponse.getHits().getTotalHits()); } @@ -187,11 +204,14 @@ public void testKeyTourismAndKeyNotAmenity() throws IOException { * Find me all places named "berlin" that have value "information" but not key "amenity" */ @Test - public void testValueInformationButKeyNotAmenity() throws IOException { - Client client = getClient(); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withValues("information").withoutKeys("amenity"); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); + public void testValueInformationButKeyNotAmenity() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withValues("information") + .withoutKeys("amenity") + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); + assertEquals(4l, searchResponse.getHits().getTotalHits()); } @@ -199,16 +219,13 @@ public void testValueInformationButKeyNotAmenity() throws IOException { * Find me all places named "berlin" that do not have the tag tourism=attraction */ @Test - public void testTagNotTourismAttraction() throws IOException { - Client client = getClient(); - Set attraction = ImmutableSet.of("attraction"); - PhotonQueryBuilder tagFilterQueryBuilder = PhotonQueryBuilder.builder("berlin", "en", Arrays.asList("en"), true).withoutTags(ImmutableMap.of("tourism", attraction)); - QueryBuilder queryBuilder = tagFilterQueryBuilder.buildQuery(); - SearchResponse searchResponse = search(client, queryBuilder); - assertEquals(16l, searchResponse.getHits().getTotalHits()); - } + public void testTagNotTourismAttraction() { + QueryBuilder queryBuilder = baseQueryBerlin() + .withoutTags(Collections.singletonMap("tourism", Collections.singleton("attraction"))) + .buildQuery(); + + SearchResponse searchResponse = search(queryBuilder); - private SearchResponse search(Client client, QueryBuilder queryBuilder) { - return client.prepareSearch("photon").setSearchType(SearchType.QUERY_AND_FETCH).setQuery(queryBuilder).execute().actionGet(); + assertEquals(16l, searchResponse.getHits().getTotalHits()); } } From 37ebbe30ea2884a3df75874f8754838eaf135f23 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Mon, 14 Jun 2021 14:57:38 +0200 Subject: [PATCH 2/3] rename tests for tag filters All query tests concerning the PhotonQueryBuilder are now collected in files called Query*Test. --- ...yBuilderSearchTest.java => QueryFilterTagValueTest.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/test/java/de/komoot/photon/query/{PhotonQueryBuilderSearchTest.java => QueryFilterTagValueTest.java} (97%) diff --git a/src/test/java/de/komoot/photon/query/PhotonQueryBuilderSearchTest.java b/src/test/java/de/komoot/photon/query/QueryFilterTagValueTest.java similarity index 97% rename from src/test/java/de/komoot/photon/query/PhotonQueryBuilderSearchTest.java rename to src/test/java/de/komoot/photon/query/QueryFilterTagValueTest.java index c8a16e6fc..678122041 100644 --- a/src/test/java/de/komoot/photon/query/PhotonQueryBuilderSearchTest.java +++ b/src/test/java/de/komoot/photon/query/QueryFilterTagValueTest.java @@ -16,7 +16,7 @@ import org.junit.Test; -public class PhotonQueryBuilderSearchTest extends ESBaseTester { +public class QueryFilterTagValueTest extends ESBaseTester { private static final String[] TAGS = new String[]{"tourism", "attraction", "tourism", "hotel", "tourism", "museum", "tourism", "information", "amenity", "parking", "amenity", "restaurant", "amenity", "information", "food", "information", "railway", "station"}; @@ -138,7 +138,7 @@ public void testKeyNotTourism() { * Find me all places named "berlin" that are tagged with the key "tourism" but not tagged with value "information". *

* Note: This is a different method of achieving the same result as - * {@link PhotonQueryBuilderSearchTest#testKeyTourismButValueNotInformation()} + * {@link QueryFilterTagValueTest#testKeyTourismButValueNotInformation()} */ @Test public void testKeyTourismAndValueNotInformation() { @@ -156,7 +156,7 @@ public void testKeyTourismAndValueNotInformation() { * Find me all places named "berlin" that are tagged with the key "tourism" but not tagged with value "information". *

* Note: This is a different method of achieving the same result as - * {@link PhotonQueryBuilderSearchTest#testKeyTourismAndValueNotInformation}. + * {@link QueryFilterTagValueTest#testKeyTourismAndValueNotInformation}. */ @Test public void testKeyTourismButValueNotInformation() { From 18f7706e860bc987f1c00db7d1c2d80d1678d915 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Mon, 14 Jun 2021 18:02:58 +0200 Subject: [PATCH 3/3] add basic search tests These tests check that all fields can be searched for as expected. They do not test correctness of order. --- .../photon/query/QueryBasicSearchTest.java | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/test/java/de/komoot/photon/query/QueryBasicSearchTest.java diff --git a/src/test/java/de/komoot/photon/query/QueryBasicSearchTest.java b/src/test/java/de/komoot/photon/query/QueryBasicSearchTest.java new file mode 100644 index 000000000..ac5240a10 --- /dev/null +++ b/src/test/java/de/komoot/photon/query/QueryBasicSearchTest.java @@ -0,0 +1,149 @@ +package de.komoot.photon.query; + +import com.google.common.collect.ImmutableMap; +import de.komoot.photon.ESBaseTester; +import de.komoot.photon.Importer; +import de.komoot.photon.PhotonDoc; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.search.SearchHits; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +/** + * Tests that the {@link PhotonQueryBuilder} produces query which can find all + * expected results at all. These tests do not check relevance. + */ +public class QueryBasicSearchTest extends ESBaseTester { + private int testDocId = 10000; + + @Before + public void setup() throws IOException { + setUpES(); + } + + private PhotonDoc createDoc(String... names) { + Map nameMap = new HashMap<>(); + + for (int i = 0; i < names.length - 1; i += 2) { + nameMap.put(names[i], names[i+1]); + } + + ++testDocId; + return new PhotonDoc(testDocId, "N", testDocId, "place", "city").names(nameMap); + } + + private SearchHits search(String query) { + QueryBuilder builder = PhotonQueryBuilder.builder(query, "en", Collections.singletonList("en"), false).buildQuery(); + return getClient().prepareSearch("photon") + .setSearchType(SearchType.QUERY_THEN_FETCH) + .setQuery(builder) + .execute() + .actionGet() + .getHits(); + } + + private SearchHits searchLenient(String query) { + QueryBuilder builder = PhotonQueryBuilder.builder(query, "en", Collections.singletonList("en"), true).buildQuery(); + return getClient().prepareSearch("photon") + .setSearchType(SearchType.QUERY_THEN_FETCH) + .setQuery(builder) + .execute() + .actionGet() + .getHits(); + } + + @Test + public void testSearchByDefaultName() { + Importer instance = makeImporter(); + instance.add(createDoc("name", "Muffle Flu")); + instance.finish(); + refresh(); + + assertEquals(1, search("muffle flu").getTotalHits()); + assertEquals(1, search("flu").getTotalHits()); + assertEquals(1, search("muffle").getTotalHits()); + assertEquals(0, search("mufle flu").getTotalHits()); + + assertEquals(1, searchLenient("mufle flu").getTotalHits()); + assertEquals(1, searchLenient("muffle flu 9").getTotalHits()); + assertEquals(0, searchLenient("huffle fluff").getTotalHits()); + } + + @Test + public void testSearchByAlternativeNames() { + final String[] alt_names = new String[]{"alt", "int", "loc", "old", "reg", "housename"}; + + Importer instance = makeImporter(); + instance.add(createDoc("name", "original", "alt_name", "alt", "old_name", "older", "int_name", "int", + "loc_name", "local", "reg_name", "regional", "addr:housename", "house", + "other_name", "other")); + instance.finish(); + refresh(); + + assertEquals(1, search("original").getTotalHits()); + assertEquals(1, search("alt").getTotalHits()); + assertEquals(1, search("older").getTotalHits()); + assertEquals(1, search("int").getTotalHits()); + assertEquals(1, search("local").getTotalHits()); + assertEquals(1, search("regional").getTotalHits()); + assertEquals(1, search("house").getTotalHits()); + assertEquals(0, search("other").getTotalHits()); + } + + @Test + public void testSearchByNameAndAddress() { + Map address = new HashMap<>(); + address.put("street", "Callino"); + address.put("city", "Madrid"); + address.put("suburb", "Quartier"); + address.put("neighbourhood", "El Block"); + address.put("county", "Montagña"); + address.put("state", "Estado"); + + Importer instance = makeImporter(); + instance.add(createDoc("name", "Castillo").address(address)); + instance.finish(); + refresh(); + + assertEquals(1, search("castillo").getTotalHits()); + assertEquals(1, search("castillo callino").getTotalHits()); + assertEquals(1, search("castillo quartier madrid").getTotalHits()); + assertEquals(1, search("castillo block montagna estado").getTotalHits()); + + assertEquals(0, search("castillo state").getTotalHits()); + //assertEquals(0, search("block montagna estado").getTotalHits()); + } + + @Test + public void testSearchWithHousenumberNamed() { + Importer instance = makeImporter(); + instance.add(createDoc("name", "Edeka").houseNumber("5").address(Collections.singletonMap("street", "Hauptstrasse"))); + instance.finish(); + refresh(); + + assertEquals(1, search("hauptstrasse 5").getTotalHits()); + assertEquals(1, search("edeka, hauptstrasse").getTotalHits()); + assertEquals(1, search("edeka, hauptstrasse 5").getTotalHits()); + assertEquals(1, search("edeka, hauptstr 5").getTotalHits()); + //assertEquals(0, search("hauptstrasse").getTotalHits()); + } + + @Test + public void testSearchWithHousenumberUnnamed() { + Importer instance = makeImporter(); + instance.add(createDoc().houseNumber("5").address(Collections.singletonMap("street", "Hauptstrasse"))); + instance.finish(); + refresh(); + + assertEquals(1, search("hauptstrasse 5").getTotalHits()); + assertEquals(0, search("hauptstrasse").getTotalHits()); + } +}