Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mimic the facets behavior like React / JS libraries #661

Open
nikunjkotecha opened this issue Jan 27, 2021 · 1 comment
Open

Mimic the facets behavior like React / JS libraries #661

nikunjkotecha opened this issue Jan 27, 2021 · 1 comment

Comments

@nikunjkotecha
Copy link

nikunjkotecha commented Jan 27, 2021

  • Algolia Client Version: 1.x but verified the issue in 2.x (latest) as well
  • Language Version: PHP 7.3

Description

When trying to filter using facets, we display all possible options from current facet when using React library (behaves like OR). For PHP client it returns only selected facet (behaves like AND even before selecting second facet in same field).

Steps To Reproduce

  • Create at-least three facets, for example color, size, brand
  • Ensure we have enough data to have multiple filter options in each facet
  • Select one size and observe the facets data in response
@nikunjkotecha
Copy link
Author

Possible solution (this for now I'm doing in https://www.drupal.org/project/search_api_algolia/ but I would love to validate and do in the library itself, I see similar behavior when using React library of Algolia)

diff --git a/docroot/modules/contrib/search_api_algolia/src/Plugin/search_api/backend/SearchApiAlgoliaBackend.php b/docroot/modules/contrib/search_api_algolia/src/Plugin/search_api/backend/SearchApiAlgoliaBackend.php
--- a/docroot/modules/contrib/search_api_algolia/src/Plugin/search_api/backend/SearchApiAlgoliaBackend.php	(date 1611759580530)
+++ b/docroot/modules/contrib/search_api_algolia/src/Plugin/search_api/backend/SearchApiAlgoliaBackend.php	(date 1611759580530)
@@ -456,10 +456,6 @@

     $this->extractConditions($query->getConditionGroup(), $algolia_options, $facets);

-    // Algolia expects indexed arrays, remove the keys.
-    if (isset($algolia_options['facetFilters'])) {
-      $algolia_options['facetFilters'] = array_values($algolia_options['facetFilters']);
-    }
     if (isset($algolia_options['disjunctiveFacets'])) {
       $algolia_options['disjunctiveFacets'] = array_values($algolia_options['disjunctiveFacets']);
     }
@@ -469,6 +465,13 @@
       unset($algolia_options['disjunctiveFacets']);
     }

+    // Algolia expects indexed arrays, remove the keys.
+    if (isset($algolia_options['facetFilters'])) {
+      $algolia_facet_filters = $algolia_options['facetFilters'];
+      $algolia_options['facetFilters'] = array_values($algolia_options['facetFilters']);
+    }
+
+
     $keys = $query->getOriginalKeys();
     $search = empty($keys) ? '*' : $keys;

@@ -480,6 +483,40 @@
     }

     if (isset($data['facets'])) {
+      // Try to mimic the behavior we have via JS / React libraries.
+      if (isset($algolia_facet_filters)) {
+        $processed_facet_filters = [];
+        $algolia_facet_fields = array_keys($algolia_facet_filters);
+
+        // One result is enough, we need facets data only.
+        $algolia_options['length'] = 1;
+        $algolia_options['offset'] = 0;
+
+        // Disable analytics for this request, same as what is observed in
+        // React library.
+        $algolia_options['analytics'] = FALSE;
+
+        // Reset the facets, we go in sequence based on weight and apply
+        // all facets except the current one.
+        // So with color, size, brand and filters applied on all 3, we will
+        // filter by none for color, filter by color for size and filter by
+        // color + size for brand.
+        // This is what we observed when using React library.
+        foreach ($algolia_facet_fields as $facet_filter_field) {
+          $algolia_options['facetFilters'] = [];
+          foreach ($processed_facet_filters as $processed_facet_filter) {
+            $algolia_options['facetFilters'][] = $algolia_facet_filters[$processed_facet_filter];
+          }
+
+          // We need only the current facet data for this request.
+          $algolia_options['facets'] = [$facet_filter_field];
+
+          $facet_data = $index->search($search, $algolia_options);
+          $processed_facet_filters[] = $facet_filter_field;
+          $data['facets'][$facet_filter_field] = $facet_data['facets'][$facet_filter_field];
+        }
+      }
+
       $results->setExtraData(
         'search_api_facets',
         $this->extractFacetsData($facets, $data['facets'])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant