Skip to content

Commit b2f87f0

Browse files
committed
Fixed: Query serializer with nested Arrays
The toParam() method was not writing nested arrays as expected causing MultipleQueries with nested arrays to return wrong responses. Expected format: query=&facetFilters=[["facet1:true"],["facet2:true"]] query=&facetFilters=[["facet1:true","facet2:true"],["facet3:true"]] query=&facetFilters=[["facet1:true"]]
1 parent 9ebfb28 commit b2f87f0

2 files changed

Lines changed: 104 additions & 13 deletions

File tree

algoliasearch-core/src/main/java/com/algolia/search/util/QueryStringUtils.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,19 @@ public static String buildQueryAsQueryParams(SearchParameters query) {
6868
// Work around for nested List<List<?>> could be improved
6969
if (tmpList.get(0) != null && tmpList.get(0) instanceof List<?>) {
7070

71-
List<List<?>> listOfList = (List) e.getValue();
72-
73-
List<?> flat =
74-
listOfList.stream()
75-
.flatMap(List::stream)
76-
.collect(Collectors.toList());
77-
78-
return String.join(",", (List) flat);
71+
List<List<Object>> listOfList = (List) e.getValue();
72+
73+
return "["
74+
+ listOfList.stream()
75+
.map(
76+
arr ->
77+
"["
78+
+ arr.stream()
79+
.map(QueryStringUtils::formatParameters)
80+
.collect(Collectors.joining(","))
81+
+ "]")
82+
.collect(Collectors.joining(","))
83+
+ "]";
7984

8085
} else {
8186
// Handling List<?>
@@ -97,6 +102,15 @@ static String buildRestrictionQueryString(SecuredApiKeyRestriction restriction)
97102
return buildQueryString(map, true);
98103
}
99104

105+
private static String formatParameters(Object parameter) {
106+
107+
if (parameter instanceof Float) {
108+
return parameter.toString();
109+
}
110+
111+
return "\"" + parameter.toString() + "\"";
112+
}
113+
100114
private static Optional<String> buildString(Map<String, String> map) {
101115
return map.entrySet().stream()
102116
.map(p -> urlEncodeUTF8(p.getKey()) + "=" + urlEncodeUTF8(p.getValue()))

algoliasearch-core/src/test/java/com/algolia/search/JacksonParserTest.java

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,33 @@ void queryWithMultipleParams() {
303303
Query query =
304304
new Query("鮄")
305305
.setTagFilters(Collections.singletonList(Collections.singletonList("(attribute)")));
306-
assertThat(query.toParam()).isEqualTo("tagFilters=%28attribute%29&query=%C3%A9%C2%AE%E2%80%9E");
306+
307+
assertThat(query.toParam())
308+
.isEqualTo("tagFilters=%5B%5B%22%28attribute%29%22%5D%5D&query=%C3%A9%C2%AE%E2%80%9E");
309+
310+
Query query2 =
311+
new Query("")
312+
.setTagFilters(Arrays.asList(Arrays.asList("a", "b"), Collections.singletonList("c")));
313+
314+
assertThat(query2.toParam())
315+
.isEqualTo("tagFilters=%5B%5B%22a%22%2C%22b%22%5D%2C%5B%22c%22%5D%5D&query=");
316+
}
317+
318+
@Test
319+
void queryWithList() {
320+
321+
Query query = new Query("").setFacets(Collections.singletonList("(attribute)"));
322+
323+
assertThat(query.toParam()).isEqualTo("query=&facets=%28attribute%29");
324+
325+
Query query2 = new Query("").setFacets(Arrays.asList("a", "b"));
326+
327+
assertThat(query2.toParam()).isEqualTo("query=&facets=a%2Cb");
328+
329+
Query query3 =
330+
new Query("").setRestrictSearchableAttributes(Collections.singletonList("attr1"));
331+
332+
assertThat(query3.toParam()).isEqualTo("query=&restrictSearchableAttributes=attr1");
307333
}
308334

309335
@Test
@@ -314,16 +340,67 @@ void queryWithBooleanParams() {
314340

315341
@Test
316342
void queryWithNestedLists() {
343+
344+
// Expected: query=&facetFilters=[["facet1:true"],["facet2:true"]]
317345
Query query =
318-
new Query("").setFacetFilters(Collections.singletonList(Arrays.asList("facet1", "facet2")));
319-
assertThat(query.toParam()).isEqualTo("facetFilters=facet1%2Cfacet2&query=");
346+
new Query("")
347+
.setFacetFilters(
348+
Arrays.asList(
349+
Collections.singletonList("facet1:true"),
350+
Collections.singletonList("facet2:true")));
320351

352+
assertThat(query.toParam())
353+
.isEqualTo(
354+
"facetFilters=%5B%5B%22facet1%3Atrue%22%5D%2C%5B%22facet2%3Atrue%22%5D%5D&query=");
355+
356+
// Expected: query=&facetFilters=[["facet1:true","facet2:true"]]
321357
Query query2 =
322358
new Query("")
323359
.setFacetFilters(
360+
Collections.singletonList(Arrays.asList("facet1:true", "facet2:true")));
361+
362+
assertThat(query2.toParam())
363+
.isEqualTo("facetFilters=%5B%5B%22facet1%3Atrue%22%2C%22facet2%3Atrue%22%5D%5D&query=");
364+
365+
// Expected: query=&facetFilters=[["facet1:true","facet2:true"],["facet3:true"]]
366+
Query query3 =
367+
new Query("")
368+
.setFacetFilters(
369+
Arrays.asList(
370+
Arrays.asList("facet1:true", "facet2:true"),
371+
Collections.singletonList("facet3:true")));
372+
373+
assertThat(query3.toParam())
374+
.isEqualTo(
375+
"facetFilters=%5B%5B%22facet1%3Atrue%22%2C%22facet2%3Atrue%22%5D%2C%5B%22facet3%3Atrue%22%5D%5D&query=");
376+
377+
// Expected: query=&facetFilters=[["facet1:true"]]
378+
Query query4 =
379+
new Query("")
380+
.setFacetFilters(Collections.singletonList(Collections.singletonList("facet1:true")));
381+
382+
assertThat(query4.toParam()).isEqualTo("facetFilters=%5B%5B%22facet1%3Atrue%22%5D%5D&query=");
383+
384+
// Expected: insideBoundingBox=[[47.3165,4.9665,47.3424,5.0201],[40.9234,2.1185,38.643,1.9916]]
385+
Query query5 =
386+
new Query("")
387+
.setInsideBoundingBox(
324388
Arrays.asList(
325-
Collections.singletonList("facet1"), Collections.singletonList("facet2")));
326-
assertThat(query2.toParam()).contains("facetFilters=facet1%2Cfacet2&query=");
389+
Arrays.asList(47.3165f, 4.9665f, 47.3424f, 5.0201f),
390+
Arrays.asList(40.9234f, 2.1185f, 38.643f, 1.9916f)));
391+
392+
assertThat(query5.toParam())
393+
.isEqualTo(
394+
"query=&insideBoundingBox=%5B%5B47.3165%2C4.9665%2C47.3424%2C5.0201%5D%2C%5B40.9234%2C2.1185%2C38.643%2C1.9916%5D%5D");
395+
396+
// Expected:insideBoundingBox=[[47.3165,4.9665,47.3424,5.0201]]
397+
Query query6 =
398+
new Query("")
399+
.setInsideBoundingBox(
400+
Collections.singletonList(Arrays.asList(47.3165f, 4.9665f, 47.3424f, 5.0201f)));
401+
402+
assertThat(query6.toParam())
403+
.isEqualTo("query=&insideBoundingBox=%5B%5B47.3165%2C4.9665%2C47.3424%2C5.0201%5D%5D");
327404
}
328405

329406
@Test

0 commit comments

Comments
 (0)