Open mahesh-makwana-web-vision opened 2 weeks ago
Hi @mahesh-makwana-web-vision : the Search Result page is designed to display only products, so you'll not be able to get categories here easily.
But on the autocompletion box, you can easily have category results if you create your category attribute with "is_searchable=1" in your setup script.
This will tell the search engine to index it and to use it when building search results.
Regards
Hello @romainruaud
So, basically, I need to create a new custom category attribute with the value "is_searchable=1," and that's it.
No other file changes are required, right?
Am I correct, or are there any additional steps needed?
Thanks
Yep, that's it. And after that, you run a full reindex of the "Elasticsuite Categories fulltext" indexer.
Regards
Let me check and update you.
Yes @romainruaud, The search works when a category custom attribute with "is_searchable=1" is added.
Now, we have a requirement: when typing a product name, we want the category containing that product to appear in the search results. Currently, only the product is showing, but not the associated category.
Is there a way to achieve this?
We planned to use a custom attribute to store all product names in a single field and make it searchable. However, this approach may create issues with synchronization when products are added or updated, as the product names would need to be kept in sync.
Do you have any suggestions for a more efficient solution?
cc: @vahonc
Thanks.
Hello @romainruaud
We created an indexer and stored the product name and SKU in that field. After reindexing, the related categories are not showing in the search results.
Can you please help us?
Thanks.
HI @mahesh-makwana-web-vision we do not provide support for custom development here.
Best regards
Hello @romainruaud and @vahonc
Below is the code for our custom attribute:
<?php
namespace VendoreName\SearchUpdate\Setup\Patch\Data;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
use Magento\Catalog\Model\Category;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
/**
* Class AddCategorySearchAttribute
*
*/
class AddCategorySearchAttribute implements DataPatchInterface, PatchRevertableInterface
{
/**
* @var ModuleDataSetupInterface
*/
private $moduleDataSetup;
/**
* @var EavSetupFactory
*/
private $eavSetupFactory;
/**
* Constructor
*
* @param ModuleDataSetupInterface $moduleDataSetup
* @param EavSetupFactory $eavSetupFactory
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
EavSetupFactory $eavSetupFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->eavSetupFactory = $eavSetupFactory;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttribute(
Category::ENTITY,
'search_content',
[
'group' => 'general',
'label' => 'Search Content',
'type' => 'text',
'input' => 'textarea',
'user_defined' => true,
'is_user_defined' => true,
'required' => false,
'sort_order' => 30,
'global' => ScopedAttributeInterface::SCOPE_STORE,
'used_in_product_listing' => true,
'backend' => '',
'system' => false,
'searchable' => true,
'filterable' => true,
'default' => null,
]
);
$this->moduleDataSetup->getConnection()->endSetup();
}
public function revert()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->removeAttribute(\Magento\Catalog\Model\Product::ENTITY, 'search_content');
$this->moduleDataSetup->getConnection()->endSetup();
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
return [];
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
return [
];
}
}
We’ve added the attribute to the Category page using the following form:
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="custom_content">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">Extra Search Content</item>
<item name="collapsible" xsi:type="boolean">true</item>
<item name="sortOrder" xsi:type="number">9999</item>
</item>
</argument>
<field name="search_content">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sortOrder" xsi:type="number">100</item>
<item name="dataType" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Product SKU + Name</item>
<item name="formElement" xsi:type="string">textarea</item>
<item name="disabled" xsi:type="boolean">true</item>
<item name="cols" xsi:type="number">10</item>
<item name="rows" xsi:type="number">5</item>
</item>
</argument>
</field>
</fieldset>
</form>
OUTPUT Category Page:
OUTPUT Catalog Search Index:
Database Table Data:
Debug Log:
[2024-10-30T08:23:33.995178+00:00] main.INFO: Request Success: {"method":"HEAD","uri":"http://localhost:9200/xtz_de_catalog_product","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.00187} []
[2024-10-30T08:23:33.995583+00:00] main.INFO: curl -XHEAD 'http://localhost:9200/xtz_de_catalog_product?pretty=true' [] []
[2024-10-30T08:23:34.007846+00:00] main.INFO: Request Success: {"method":"POST","uri":"http://localhost:9200/xtz_de_thesaurus/_analyze","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.001145} []
[2024-10-30T08:23:34.008053+00:00] main.INFO: curl -XPOST 'http://localhost:9200/xtz_de_thesaurus/_analyze?pretty=true' -d '{"text":"5020 01802","analyzer":"synonym"}' [] []
[2024-10-30T08:23:34.008735+00:00] main.INFO: Request Success: {"method":"POST","uri":"http://localhost:9200/xtz_de_thesaurus/_analyze","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.000372} []
[2024-10-30T08:23:34.008898+00:00] main.INFO: curl -XPOST 'http://localhost:9200/xtz_de_thesaurus/_analyze?pretty=true' -d '{"text":"5020 01802","analyzer":"expansion"}' [] []
[2024-10-30T08:23:34.074397+00:00] main.INFO: Request Success: {"method":"GET","uri":"http://localhost/","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.000605} []
[2024-10-30T08:23:34.074609+00:00] main.INFO: curl -XGET 'http://localhost/?pretty=true' [] []
[2024-10-30T08:23:34.113484+00:00] main.INFO: Request Success: {"method":"POST","uri":"http://localhost:9200/xtz_de_catalog_product/_search","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.037828} []
[2024-10-30T08:23:34.113798+00:00] main.INFO: curl -XPOST 'http://localhost:9200/xtz_de_catalog_product/_search?pretty=true' -d '{"size":5,"sort":[{"search_query.position":{"order":"ASC","missing":"_last","unmapped_type":"keyword","nested":{"path":"search_query","filter":{"terms":{"search_query.query_id":["17707"],"boost":1}}},"mode":"min"}},{"_score":{"order":"desc"}},{"entity_id":{"order":"desc","missing":"_first","unmapped_type":"keyword"}}],"from":0,"query":{"bool":{"filter":{"bool":{"must":[{"term":{"stock.is_in_stock":{"value":true,"boost":1}}},{"terms":{"visibility":[3,4],"boost":1}},{"bool":{"must_not":[{"nested":{"path":"search_query","score_mode":"none","query":{"bool":{"must":[{"term":{"search_query.query_id":{"value":17707,"boost":1}}},{"term":{"search_query.is_blacklisted":{"value":true,"boost":1}}}],"must_not":[],"should":[],"boost":1}},"boost":1}}],"boost":1}}],"must_not":[],"should":[],"boost":1}},"must":{"bool":{"must":[],"must_not":[],"should":[{"bool":{"filter":{"multi_match":{"query":"5020-01802","fields":["search^1"],"minimum_should_match":"95%","tie_breaker":1,"boost":1,"type":"best_fields"}},"must":{"multi_match":{"query":"5020-01802","fields":["search^1","name.standard^5","sku.reference^10","description.standard^9","short_description.standard^9","option_text_manufacturer.standard^10","option_text_length.standard^8","option_text_inner_diameter.standard^8","option_text_packing_brand.standard^10","search.whitespace^10","name.whitespace^50","sku.whitespace^100","description.whitespace^90","short_description.whitespace^90","option_text_manufacturer.whitespace^100","option_text_length.whitespace^80","option_text_inner_diameter.whitespace^80","option_text_packing_brand.whitespace^100","name.sortable^100","sku.sortable^200","option_text_manufacturer.sortable^200","option_text_length.sortable^160","option_text_bet_surface_area_in_m2g.sortable^20","option_text_endcapping.sortable^20","option_text_carbon_load_in_percent_c.sortable^20"],"minimum_should_match":1,"tie_breaker":1.0,"boost":1,"type":"best_fields"}},"_name":"EXACT","boost":1}}],"minimum_should_match":1,"boost":1}},"boost":1}},"track_total_hits":0}' [] []
[2024-10-30T08:23:34.660982+00:00] main.INFO: Request Success: {"method":"HEAD","uri":"http://localhost:9200/xtz_de_catalog_category","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.000948} []
[2024-10-30T08:23:34.661192+00:00] main.INFO: curl -XHEAD 'http://localhost:9200/xtz_de_catalog_category?pretty=true' [] []
[2024-10-30T08:23:34.662509+00:00] main.INFO: Request Success: {"method":"POST","uri":"http://localhost:9200/xtz_de_thesaurus/_analyze","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.000667} []
[2024-10-30T08:23:34.662688+00:00] main.INFO: curl -XPOST 'http://localhost:9200/xtz_de_thesaurus/_analyze?pretty=true' -d '{"text":"5020 01802","analyzer":"synonym"}' [] []
[2024-10-30T08:23:34.663443+00:00] main.INFO: Request Success: {"method":"POST","uri":"http://localhost:9200/xtz_de_thesaurus/_analyze","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.000395} []
[2024-10-30T08:23:34.663605+00:00] main.INFO: curl -XPOST 'http://localhost:9200/xtz_de_thesaurus/_analyze?pretty=true' -d '{"text":"5020 01802","analyzer":"expansion"}' [] []
[2024-10-30T08:23:34.671286+00:00] main.INFO: Request Success: {"method":"POST","uri":"http://localhost:9200/xtz_de_catalog_category/_search","port":"9200","headers":{"Host":["localhost"],"Content-Type":["application/json"],"Accept":["application/json"],"User-Agent":["opensearch-php/2.3.1 (Linux 4.18.0; PHP 8.2.25)"]},"HTTP code":200,"duration":0.004866} []
[2024-10-30T08:23:34.671471+00:00] main.INFO: curl -XPOST 'http://localhost:9200/xtz_de_catalog_category/_search?pretty=true' -d '{"size":3,"sort":[{"_score":{"order":"desc"}},{"entity_id":{"order":"desc","missing":"_first","unmapped_type":"keyword"}}],"from":0,"query":{"bool":{"filter":{"terms":{"is_displayed_in_autocomplete":[true],"boost":1}},"must":{"bool":{"must":[],"must_not":[],"should":[{"bool":{"filter":{"multi_match":{"query":"5020-01802","fields":["search^1"],"minimum_should_match":"95%","tie_breaker":1,"boost":1,"type":"best_fields"}},"must":{"multi_match":{"query":"5020-01802","fields":["search^1","search.whitespace^10"],"minimum_should_match":1,"tie_breaker":1.0,"boost":1,"type":"best_fields"}},"_name":"EXACT","boost":1}},{"bool":{"filter":{"multi_match":{"query":"5020-01802","fields":["search^1"],"minimum_should_match":"95%","tie_breaker":1,"boost":1,"type":"best_fields"}},"must":{"multi_match":{"query":"5020-01802","fields":["search^1","search.whitespace^10"],"minimum_should_match":1,"tie_breaker":1.0,"boost":1,"type":"best_fields"}},"_name":"EXACT","boost":1}}],"minimum_should_match":1,"boost":1}},"boost":1}},"track_total_hits":100000}' [] []
ISSUE:
The content is visible on the Category page and is indexed, but when we perform a search, the related categories are not appear in the search results.
We are using Magento 2.4.7-p2 with ElasticSuite 2.11.9 on Elasticsearch 8.15.3. We’ve implemented the is_searchable=1 attribute as per your prior confirmation, but we’re still facing issues.
Could you please help us troubleshoot this?
Thank you.
@mahesh-makwana-web-vision if you are willing to display Categories on the search result page, you'll have to implement this yourself :
@romainruaud
When we search by SKU or product name, we want the related category to appear in the search results. Currently, if the search string matches, only the category name is displayed.
To address this, I added a custom attribute to the category and stored all product names and SKUs within this attribute. I also set this custom field to is_searchable=1, but the category name still doesn’t appear based on the custom attribute value.
I’ve added the code that was previously shared. Could you please guide me on where I might be going wrong?
Thanks.
Hi, I've explained what you should try to do.
You can take inspiration from this module : https://github.com/Smile-SA/magento2-module-elasticsuite-cms-search
Just replace the frontend part which is fetching "PageCollection" with a "CategoryCollection" and you should be all good.
Best regards
Okay @romainruaud
Let me check and update you.
Thanks.
Is there a way to use custom category attributes in the search popup and search page, similar to how they are used for products?
I found this file, but I'm not sure how to modify it to include a custom attribute.
Path:
Smile\ElasticsuiteCatalog\Model\ResourceModel\Category\Indexer\Fulltext\Action\Full
Can you please help me make categories searchable by their custom attribute?
The custom attribute is of the text datatype.
cc: @romainruaud @vahonc
Thanks.