elasticsuite
elasticsuite copied to clipboard
How to exclude the SKU from the search?
Merchendaiser requested to exclude searches by sku attribute.
I set in the settings. Stores->Attributes->Product->Storefront Properties->Search Configuration->Use in Search - "NO" But it doesn't work.
Is there a proper way how to do this?
Regards
Hello @ruvor1991
That's by design, because the XML configuration file has precedence over DB changes.
https://github.com/Smile-SA/elasticsuite/blob/2.11.x/src/module-elasticsuite-catalog/etc/elasticsuite_indices.xml#L33
Since the SKU is set to isSearchable=1 through the XML file, disabling it through the back-office is likely to have no effect.
You should try to disable it via XML, clear the cache and then run reindex.
BR, Vadym
Hello @vahonc ,
I also tried to put 0 in the configuration you mentioned vendor/smile/elasticsuite/src/module-elasticsuite-catalog/etc/elasticsuite_indices.xml
<field name="sku" type="text">
<isSearchable>0</isSearchable>
<isUsedForSortBy>0</isUsedForSortBy>
<isUsedInSpellcheck>0</isUsedInSpellcheck>
<isFilterable>1</isFilterable>
<defaultSearchAnalyzer>reference</defaultSearchAnalyzer>
</field>
Then did reindex and flushed the cache. I did not get any effect.
This is my debug information:
{
"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":"test_product",
"fields":[
"search^1",
"sku^1"
],
"minimum_should_match":"100%",
"tie_breaker":1,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"must":{
"multi_match":{
"query":"test_product",
"fields":[
"search^1",
"search.whitespace^10"
],
"minimum_should_match":1,
"tie_breaker":1.0,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"boost":1
}
},
{
"bool":{
"filter":{
"multi_match":{
"query":"test_product",
"fields":[
"search^1",
"sku^1"
],
"minimum_should_match":"100%",
"tie_breaker":1,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"must":{
"multi_match":{
"query":"test_product",
"fields":[
"search^1",
"search.whitespace^10"
],
"minimum_should_match":1,
"tie_breaker":1.0,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"boost":1
}
}
],
"minimum_should_match":1,
"boost":1
}
},
"boost":1
}
},
"track_total_hits":100000
}
Thank you for your reply
@ruvor1991,
Which versions of Magento and ElasticSuite you are using?
BR, Vadym
Hi @ruvor1991
I can reproduce what you're describing locally.
It seems that we hardcoded the SKU here : https://github.com/Smile-SA/elasticsuite/blob/2.11.x/src/module-elasticsuite-core/Search/Request/Query/Fulltext/QueryBuilder.php#L124
We'll have to re-think about it with @rbayet since for me, the SKU is supposed to be dynamically added when needed at line 127 and 129 (if the appropriate config is set).
That being said, this query part is only the one used for filtering out products, the query part used to build the matching is the other one :
"multi_match":{
"query":"test_product",
"fields":[
"search^1",
"search.whitespace^10"
],
"minimum_should_match":1,
"tie_breaker":1.0,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
So actually, there is no try to match on sku field here, only on "search", and since sku is not searchable, it's not supposed to be copied on "search" either.
What I found when debugging this locally, was the fact that making a "bin/magento cache:clean" was NOT cleaning the aggregated version of the elasticsuite_indices.xml file, because this was not intended to be tagged as using one of the default Magento cache tag (config, layout, eav etc...).
So the PR #3191 should allow to properly clearing the cache.
My guess is that you've been on the same edge-case as me locally, and even after changing your XML and doing a cache:clean, your sku field still had "copy_to : search" in the mapping due to this unproper cache expiration.
If you're using Redis you can do a "flush all" to be sure that the cache is expired, then reindex.
If you're using filesystem cache, "rm -rf var/cache/**" should ensure the precedent version of xml has been purged as well.
Regards
Hi, Romain
Magento CLI 2.4.6-p4 "name": "smile/elasticsuite", "version": "2.11.5.1",
I have cleared the redis : "flush all" cleared the magento 2 cache. Nothing changed
{
"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":"test_product",
"fields":[
"search^1",
"sku^1"
],
"minimum_should_match":"100%",
"tie_breaker":1,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"must":{
"multi_match":{
"query":"test_product",
"fields":[
"search^1",
"search.whitespace^10"
],
"minimum_should_match":1,
"tie_breaker":1.0,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"boost":1
}
},
{
"bool":{
"filter":{
"multi_match":{
"query":"test_product",
"fields":[
"search^1",
"sku^1"
],
"minimum_should_match":"100%",
"tie_breaker":1,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"must":{
"multi_match":{
"query":"test_product",
"fields":[
"search^1",
"search.whitespace^10"
],
"minimum_should_match":1,
"tie_breaker":1.0,
"boost":1,
"type":"best_fields",
"cutoff_frequency":0.15
}
},
"boost":1
}
}
],
"minimum_should_match":1,
"boost":1
}
},
"boost":1
}
},
"track_total_hits":100000
}
Also I did back <isSearchable>1</isSearchable> just to check and get the same JSON in the debug.log The other attempt I made with https://github.com/Smile-SA/elasticsuite/blob/2.11.x/src/module-elasticsuite-core/Search/Request/Query/Fulltext/QueryBuilder.php#L124 with changing this
$fields = array_fill_keys([MappingInterface::DEFAULT_SEARCH_FIELD, 'sku'], 1);
On this
$fields = array_fill_keys([MappingInterface::DEFAULT_SEARCH_FIELD], 1);
And get the same result.
Regards
@ruvor1991 as I said previously, there is no issue to have the sku being injected in the "filter" part of the query. That will not impact the results.
==> We'll fix this, but it's mostly cosmetic / code cleaning issues and has no functional impact.
We can see that the search part of your query is not targeting the sku but only the search
and search.whitespace
field so it's normal.
Can you give us more details about your use case ? is "test_product" the SKU of your product ? "test" and "product" token might be matching plenty of other fields and products of your catalog, did you try with something really containing the SKU ?
On top of that, setting the SKU as "not searchable" will change the mapping for the field, removing the "copy_to : search" that it was having previously, but if you don't run a full reindex, the old data will still be there.
So the proper steps to check if you are having an issue would be :
- Create a product and give it a SKU like "24-MB01"
- Set the SKU as not searchable as per your initial issue
- Clear the cache (redis-cli flushall) until my PR is released.
- Do a full reindex
- Search for "24-MB01" on frontend
- You should have no results, it's likely that you'll not even have an exact match query either, but a spelling one, due to the fact that the token will not be found in the index.
- You'll probably still the the "sku" being used for the multi_match filter query, but this has no effect.
The other attempt I made with https://github.com/Smile-SA/elasticsuite/blob/2.11.x/src/module-elasticsuite-core/Search/Request/Query/Fulltext/QueryBuilder.php#L124 with changing this
$fields = array_fill_keys([MappingInterface::DEFAULT_SEARCH_FIELD, 'sku'], 1);
On this $fields = array_fill_keys([MappingInterface::DEFAULT_SEARCH_FIELD], 1);
And get the same result.
On my dev env, if I remove this hardcoded "sku", it's get out of the generated query.
Hello @ruvor1991,
The second fix by @romainruaud has been merged in branches 2.10.x and 2.11.x. So, now :
- You should now be able to properly clean the specific "Elasticsuite" cache after changing the searchability of the sku in the XML and/or in admin (due to PR #3191)
- The query system will no longer harcode the use of the "sku" attribute in exact match queries filters
You should be able to test this with a composer require smile/elasticsuite:2.11.x-dev
+ cache clearing + full catalogsearch_fulltext reindexing if you wanrt to test prior to our next releases.
Regards,