From f0fc00fca417662a1456375c307c2238e0cb633c Mon Sep 17 00:00:00 2001 From: Nathan McBride Date: Wed, 3 May 2023 21:42:10 +1000 Subject: [PATCH] Fix autocomplete and searchable attributes --- Adapter/Client.php | 2 +- Helper/ConfigChangeHelper.php | 74 +++--- README.md | 14 ++ view/frontend/layout/default.xml | 6 + view/frontend/requirejs-config.js | 7 + view/frontend/web/js/autocomplete.js | 212 ++++++++++++++++++ .../web/js/internals/autocompleteConfig.js | 2 +- view/frontend/web/js/typesense.min.js | 2 + 8 files changed, 279 insertions(+), 40 deletions(-) create mode 100644 view/frontend/requirejs-config.js create mode 100644 view/frontend/web/js/autocomplete.js create mode 100644 view/frontend/web/js/typesense.min.js diff --git a/Adapter/Client.php b/Adapter/Client.php index 54dd82e..4d4d33d 100644 --- a/Adapter/Client.php +++ b/Adapter/Client.php @@ -64,7 +64,7 @@ public function deleteIndex(string $indexName): array */ public function addData($indexName, $data) { - $facets = []; + $facets = $this->getFacets(); foreach ($data as &$item) { $item['id'] = (string)$item['objectID']; $item['objectID'] = (string)$item['objectID']; diff --git a/Helper/ConfigChangeHelper.php b/Helper/ConfigChangeHelper.php index 270e888..98071a6 100644 --- a/Helper/ConfigChangeHelper.php +++ b/Helper/ConfigChangeHelper.php @@ -2,6 +2,7 @@ namespace Develo\Typesense\Helper; +use Algolia\AlgoliaSearch\Helper\ConfigHelper; use Algolia\AlgoliaSearch\Helper\Data as AlgoliaHelper; use Algolia\AlgoliaSearch\Helper\ConfigHelper as AlgoliaConfigHelper; use Develo\Typesense\Adapter\Client; @@ -136,7 +137,6 @@ public function setCollectionConfig() unset($existingCollections[$indexName]); } - $this->typeSenseCollecitons->create( [ 'name' => $indexName, @@ -189,7 +189,20 @@ public function getFields(array $facets, array $sortingAttributes, string $index ['name' => 'objectID', 'type' => 'string', 'facet' => true], ['name' => 'categories', 'type' => 'object', 'facet' => true], ['name' => 'visibility_search', 'type' => 'int64'], - ['name' => 'visibility_catalog', 'type' => 'int64', 'facet' => true] + ['name' => 'visibility_catalog', 'type' => 'int64', 'facet' => true], + [ + 'name' => 'price_default', + 'type' => 'float', + 'sort' => true, + 'facet' => true + ], + + [ + 'name' => 'sku', + 'type' => 'string[]', + 'facet' => in_array('sku', $facets), + 'sort' => in_array('sku', $sortingAttributes) + ] ]; // The hierarchal menu widget expects 10 levels of category. @@ -222,7 +235,7 @@ public function getFields(array $facets, array $sortingAttributes, string $index $attributeCodes = []; foreach ($attributes as $attribute) { - if ($attribute['searchable'] === '1' || in_array($attribute['attribute'], $facets)) { + if ($attribute['searchable'] === '1') { $attributeCodes[] = $attribute['attribute']; } } @@ -234,44 +247,19 @@ public function getFields(array $facets, array $sortingAttributes, string $index $attributeCollection = $this->attributeRepository->getList($entityTypeCode, $searchCriteria->create()); $fields = []; - foreach ($attributeCollection->getItems() as $attribute) { - if ($attribute->getAttributeCode() === 'price') { - $fields[] = [ - 'name' => $attribute->getAttributeCode(), - 'type' => 'object' - ]; - - $fields[] = [ - 'name' => 'price_default', - 'type' => 'float', - 'sort' => true - ]; - - continue; - } - - if ($attribute->getAttributeCode() === 'sku') { - $fields[] = [ - 'name' => $attribute->getAttributeCode(), - 'type' => 'string[]', - 'facet' => in_array($attribute->getAttributeCode(), $facets), - 'sort' => in_array($attribute->getAttributeCode(), $sortingAttributes), - ]; + foreach ($attributeCollection->getItems() as $attribute) { + if (in_array($attribute->getAttributeCode(), ['price', 'sku'])) { continue; } $isFacet = in_array($attribute->getAttributeCode(), $facets); - if (!$isFacet) { - continue; - } - $fields[] = [ 'name' => $attribute->getAttributeCode(), - 'type' => 'string[]', + 'type' => $isFacet ? 'string[]' : 'string', 'facet' => $isFacet, - 'sort' => false, + 'sort' => in_array($attribute->getAttributeCode(), $sortingAttributes), 'optional' => !$attribute->getIsRequired() ]; } @@ -286,14 +274,24 @@ public function getFields(array $facets, array $sortingAttributes, string $index public function getSearchableAttributes(string $index = self::INDEX_PRODUCTS): string { $attributes = []; - foreach ($this->getFields([], [], $index) as $field) { - if (!in_array($field['type'], ['string', 'string[]'])) { - continue; - } + switch ($index) { + case 'products': + $attributes = $this->algoliaConfigHelper->getProductAdditionalAttributes(); + break; + case 'categories': + $attributes = $this->algoliaConfigHelper->getCategoryAdditionalAttributes(); + break; + case 'pages': + return 'name,slug'; + } - $attributes[] = $field['name']; + $searchableAttributes = []; + foreach ($attributes as $attribute) { + if ($attribute['searchable'] === '1') { + $searchableAttributes[] = $attribute['attribute']; + } } - return implode(',', $attributes); + return implode(',', $searchableAttributes); } } diff --git a/README.md b/README.md index 26bf033..4d6b103 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,20 @@ For more information on customizing the Algolia module, please refer to the foll - [Customizing Instant Search Page](https://www.algolia.com/doc/integration/magento-2/customize/instant-search-page/) - [Customizing Custom Front-end Events](https://www.algolia.com/doc/integration/magento-2/customize/custom-front-end-events/) +When migrating from Algolia, you will need to remove "Price" from the facets and review the Product and Category searchable attributes. Typesense is much more strict when querying so if an attribute does not exist it will throw an error. + +Review the following config and set searchable to "No" when applicable: + +Settings > Algolia > Products > Attributes + +## Debugging config + +You may get errors such as: + +`pesense-adapter.js:1 Uncaught (in promise) Error: 404 - Could not find a field named "path" in the schema.` + +This is because you either have a searchable attribute for products which does not exist, or perhaps a facet attribute which does not exist. You should remove the attribute from these areas and try again. + ## Documentation For more information about Typesense, check out their [official documentation](https://typesense.org/docs/). diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml index ad6a857..c32dc29 100644 --- a/view/frontend/layout/default.xml +++ b/view/frontend/layout/default.xml @@ -4,4 +4,10 @@