algolia / algoliasearch-client-android

Algolia Search API Client for Android
MIT License
99 stars 29 forks source link

searchDisjunctiveFacetingAsync breaks on facet values with commas #542

Closed PLNech closed 6 years ago

PLNech commented 6 years ago

The query is sent with facetFilters=(lvl0:Dom, byt a záhrada), which brings no result. Indeed, it should be facetFilters=[\"lvl0:Dom, byt a záhrada\"] which works as expected.

This prompts to a refactoring of searchDisjunctiveFacetingAsync, which was already requested in a TODO.

PLNech commented 6 years ago

@clement-leprovost, would love your take on this one before refactoring.

PLNech commented 6 years ago

In the meantime, workaround consists in computing manually filters:

// Create the query, refinements, disjunctiveFacets
Query query = new Query().setFacets("*").setMaxValuesPerFacet(20);
java.util.HashMap<String, List<String>> refinements = new HashMap<>();
refinements.put("office_region", Collections.singletonList("Prešovský"));
refinements.put("lvl0", Collections.singletonList("Dom, byt a záhrada"));
Collection<String> disjunctiveFacets = Collections.singletonList("lvl0");

// Manually build the filters string using the refinements
StringJoiner joinAnd = new StringJoiner(" AND ");
for (Map.Entry<String, List<String>> entry : refinements.entrySet()) {
    StringJoiner joinOr = new StringJoiner(" OR ");
    String attribute = entry.getKey();
    for (String value : entry.getValue()) {
        joinOr.add(attribute + ":\"" + value + "\"");
    }
    joinAnd.add(joinOr.toString());
}
query.setFilters(joinAnd.toString());

// Trigger disjunctive search with empty refinements parameter
index.searchDisjunctiveFacetingAsync(query, disjunctiveFacets, new HashMap<String, ArrayList<String>>(), new CompletionHandler() {
    @Override
    public void requestCompleted(JSONObject jsonObject, AlgoliaException e) {
        if (jsonObject != null) {
            Log.e("searchDisjunctive", "requestCompleted success: " + jsonObject.optString("nbHits"));
        }
        if (e != null) Log.e("searchDisjunctive", "requestCompleted error: " + e);
    }
});
clement-leprovost commented 6 years ago

Indeed parentheses make no sense when used with facetFilters. The Git blame says it's me, but I just moved around some code. 😇

Using filters instead of facetFilters will bring other issues, as this parameter also handles numeric filters and tag filters, and its syntax is different. I would stick to facetFilters for the time being. It's not deprecated. We just recommend using filters for manually input queries (because it supports a more user-friendly, SQL-like syntax); but facetFilters still makes a lot of sense for automatically generated filters.

PLNech commented 6 years ago

Fix released in v3.21.13.