Skip to content

Commit 0e58180

Browse files
authored
fix: optional filters deserialization (#771)
1 parent 20793bf commit 0e58180

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

algoliasearch-core/src/main/java/com/algolia/search/models/indexing/FiltersJsonDeserializer.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,12 @@ public List<List<String>> deserialize(JsonParser p, DeserializationContext ctxt)
2929

3030
switch (currentToken) {
3131
case START_ARRAY:
32-
List list = p.readValueAs(List.class);
33-
if (list.stream().allMatch(String.class::isInstance)) { // are all elements strings?
34-
result = Collections.singletonList(list);
35-
} else {
36-
result = buildFilters(list);
37-
}
32+
List<Object> list = p.readValueAs(List.class);
33+
result = buildFilters(list);
3834
break;
3935
case VALUE_STRING:
40-
result = Collections.singletonList(Arrays.asList(p.getValueAsString().split(",")));
36+
String string = p.getValueAsString();
37+
result = buildFilters(string);
4138
break;
4239
case VALUE_NULL:
4340
break;
@@ -49,6 +46,7 @@ public List<List<String>> deserialize(JsonParser p, DeserializationContext ctxt)
4946
return result;
5047
}
5148

49+
/** Build filters from a list */
5250
@SuppressWarnings("unchecked")
5351
private List<List<String>> buildFilters(List list) {
5452
return (List<List<String>>)
@@ -63,4 +61,21 @@ private List<List<String>> buildFilters(List list) {
6361
})
6462
.collect(Collectors.toList());
6563
}
64+
65+
/** Build filters from (legacy) string */
66+
private List<List<String>> buildFilters(String string) {
67+
// Extract groups: "(A:1,B:2),C:3" -> ["(A:1,B:2)","C:3"]
68+
List<String> groups = Arrays.asList(string.split(",(?![^()]*\\))"));
69+
return groups.stream()
70+
.map(
71+
group -> {
72+
if (group.startsWith("(") && group.endsWith(")")) {
73+
String input = group.substring(1, group.length() - 1);
74+
return Arrays.asList(input.split(","));
75+
} else {
76+
return Collections.singletonList(group);
77+
}
78+
})
79+
.collect(Collectors.toList());
80+
}
6681
}

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,18 +171,17 @@ void serializeFacetFilters() throws IOException {
171171
@ValueSource(strings = {"facetFilters", "optionalFilters", "tagFilters", "numericFilters"})
172172
void testLegacyFiltersFormat(String input) throws IOException {
173173

174-
// Testing "one string" legacy filters => should be converted to "ORED" nested filters
175-
// [["color:green","color:yellow"]]
174+
// Testing "one string" legacy filters => should be converted to "ANDED" filters
175+
// [["color:green"],["color:yellow"]]
176176
String stringFilters = String.format("{\"%s\":\"color:green,color:yellow\"}", input);
177-
178-
assertOREDResult(
177+
assertANDEDListResult(
179178
extractFilters(
180179
Defaults.getObjectMapper().readValue(stringFilters, ConsequenceParams.class), input));
181180

182-
// Testing "one array" legacy filters => should be converted to "ORED" nested filters
183-
// [["color:green","color:yellow"]]
181+
// Testing "one array" legacy filters => should be converted to "ANDED" filters
182+
// [["color:green"],["color:yellow"]]
184183
String arrayFilters = String.format("{\"%s\":[\"color:green\",\"color:yellow\"]}", input);
185-
assertOREDResult(
184+
assertANDEDListResult(
186185
extractFilters(
187186
Defaults.getObjectMapper().readValue(arrayFilters, ConsequenceParams.class), input));
188187

@@ -193,8 +192,17 @@ void testLegacyFiltersFormat(String input) throws IOException {
193192
Defaults.getObjectMapper().readValue(nestedArrayFilters, ConsequenceParams.class),
194193
input));
195194

195+
// Testing "one string with parenthesis" legacy filters => should be converted to "ORED" filters
196+
// [["color:green", "color:yellow"], ["color:blue"]]
197+
String stringParenthesisFilters =
198+
String.format("{\"%s\":\"(color:green,color:yellow),color:blue\"}", input);
199+
assertOREDLatestResult(
200+
extractFilters(
201+
Defaults.getObjectMapper().readValue(stringParenthesisFilters, ConsequenceParams.class),
202+
input));
203+
196204
// Testing mixed case with array and string
197-
// [["color:green","color:yellow"],"color:blue"]
205+
// [["color:green","color:yellow"], ["color:blue"]]
198206
String stringAndArrayFilters =
199207
String.format("{\"%s\":[[\"color:green\",\"color:yellow\"],\"color:blue\"]}", input);
200208
List<List<String>> mixedDeserialized =
@@ -242,6 +250,14 @@ void assertOREDResult(List<List<String>> result) {
242250
assertThat(result.get(0)).containsSequence("color:yellow");
243251
}
244252

253+
void assertANDEDListResult(List<List<String>> result) {
254+
assertThat(result).hasSize(2);
255+
assertThat(result.get(0)).hasSize(1);
256+
assertThat(result.get(0)).containsSequence("color:green");
257+
assertThat(result.get(1)).hasSize(1);
258+
assertThat(result.get(1)).containsSequence("color:yellow");
259+
}
260+
245261
void assertOREDLatestResult(List<List<String>> result) {
246262
assertThat(result).hasSize(2);
247263
assertThat(result.get(0)).hasSize(2);

0 commit comments

Comments
 (0)