I added new filter using plugin for Magento\Framework\Search\Request\Config\FilesystemReader
public function afterRead( \Magento\Framework\Config\ReaderInterface $subject, array $result, $scope = null ) { $aggregations = [ 'vendor_stock_bucket' => [ 'name' => 'vendor_stock_bucket', 'field' => 'vendor_stock_status', 'type' => 'termBucket', 'metrics' => [ [ 'type' => 'count' ] ] ] ]; $vendor_stock_status_query = [ 'name' => 'vendor_stock_status_query', 'type' => 'filteredQuery', 'filterReference' => [ [ 'clause' => 'must', 'ref' => 'vendor_stock_status_filter' ] ] ]; $filters = [ 'vendor_stock_status_filter' => [ 'type' => 'termFilter', 'name' => 'vendor_stock_status_filter', 'field' => 'vendor_stock_status', 'value' => '$vendor_stock_status$' ] ]; $queryReference = [ [ 'clause' => 'must', 'ref' => 'vendor_stock_status_query' ] ]; $result = array_merge_recursive($result, [ 'catalog_view_container' => [ 'queries' => [ 'catalog_view_container' => [ 'queryReference' => $queryReference ], 'vendor_stock_status_query' => $vendor_stock_status_query ], 'filters' => $filters ] ]); $result = array_merge_recursive($result, [ 'catalog_view_container' => [ 'aggregations' => $aggregations ] ]); $result = array_merge_recursive($result, [ 'quick_search_container' => [ 'queries' => [ 'quick_search_container' => [ 'queryReference' => $queryReference ], 'vendor_stock_status_query' => $vendor_stock_status_query ], 'filters' => $filters ] ]); $result = array_merge_recursive($result, [ 'quick_search_container' => [ 'aggregations' => $aggregations ] ]); return $result; }
Now sometimes I have error "The bucket doesn't exist." for added bucket. After cache flush it works correct.
Due to caching - most of the time the filters are not displayed at all because there was an error when _getItemsData() for the new filter. The worst thing is that I can't reproduce it locally. Maybe someone has an idea why the error may occure periodically?
Solved! Go to Solution.
The problem was solved by replacing the plugin with the search_request.xml file with the code
<?xml version="1.0"?> <!-- /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ --> <requests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Search/etc/search_request.xsd"> <request query="catalog_view_container" index="catalogsearch_fulltext"> <dimensions> <dimension name="scope" value="default"/> </dimensions> <queries> <query xsi:type="boolQuery" name="catalog_view_container" boost="1"> <queryReference clause="must" ref="vendor_stock_status_query"/> </query> <query xsi:type="filteredQuery" name="vendor_stock_status_query"> <filterReference clause="must" ref="vendor_stock_status_filter" /> </query> </queries> <filters> <filter xsi:type="termFilter" name="vendor_stock_status_filter" field="vendor_stock_status" value="$vendor_stock_status$"/> </filters> <aggregations> <bucket name="vendor_stock_status_bucket" field="vendor_stock_status" xsi:type="termBucket"> <metrics> <metric type="count"/> </metrics> </bucket> </aggregations> <from>0</from> <size>10000</size> </request> <request query="quick_search_container" index="catalogsearch_fulltext"> <dimensions> <dimension name="scope" value="default"/> </dimensions> <queries> <query xsi:type="boolQuery" name="quick_search_container" boost="1"> <queryReference clause="must" ref="vendor_stock_status_query"/> </query> <query xsi:type="filteredQuery" name="vendor_stock_status_query"> <filterReference clause="must" ref="vendor_stock_status_filter" /> </query> </queries> <filters> <filter xsi:type="termFilter" name="vendor_stock_status_filter" field="vendor_stock_status" value="$vendor_stock_status$"/> </filters> <aggregations> <bucket name="vendor_stock_status_bucket" field="vendor_stock_status" xsi:type="termBucket"> <metrics> <metric type="count"/> </metrics> </bucket> </aggregations> <from>0</from> <size>10000</size> </request> </requests>
Can you please try below things and let me know if any of these works for you
Use array_replace_recursive instead of array_merge_recursive, or take a closer look at how your arrays are being combined. This can help prevent unexpected issues with nested structures.
Double-check your custom cache invalidation logic to make sure it’s working as expected. Pay special attention to cache tags related to the search configuration to ensure they’re being properly handled.
Look into the Elasticsearch query and response logs to verify that your custom bucket is being included in the search queries and the results.
Review the _getItemsData() method in your custom filter to confirm that the bucket consistently appears in the search results without fail.
Try disabling cache for the search configuration while debugging to see if the cache is causing the issue. This will help pinpoint whether caching is the root of the problem.
If this help please give me a thumbs up.
Regards!
Ajaruden Parihar
Magento Master and Instructor @LTS HUB
https://www.ltshub.com/
@ajarudeenpd530 ,Thank you for your reply.
I rewrote array_merge_recursive to the code below.
We do not use custom cache invalidation logic.
It is in the _getItemsData() custom filter method that the bucket error sometimes occurs. I added try/catch there and there are no problems with other filters, only with my own.
protected function _getItemsData() { if ($this->getLayer()->getProductCollection()->getFlag(self::IN_STOCK_COLLECTION_FLAG)) { return []; } $data = []; foreach ($this->getStatuses() as $status) { $count = $this->getCountByStatus($status); if($count > 0) { $data[] = [ 'label' => $this->getLabel($status), 'value' => $status, 'count' => $count ]; } } return $data; } public function getCountByStatus($status) { try { $productCollection = $this->getLayer()->getProductCollection(); $optionsFacetedData = $productCollection->getFacetedData('vendor_stock_status'); return $optionsFacetedData[$status]['count'] ?? 0; } catch (\Exception $exception) { $this->logger->error($exception->getMessage()); return 0; } }
The cache has not yet been turned off in production. The problem is that the issue is not reproduced either locally or on the test environment. Witch cache or no
Maybe there will be some other ideas?
public function afterRead( \Magento\Framework\Config\ReaderInterface $subject, array $result ) { $requestNames = ['catalog_view_container', 'quick_search_container']; $attributeCode = 'vendor_stock_status'; foreach ($requestNames as $requestName) { if (!empty($result[$requestName])) { $filterName = $attributeCode . '_filter'; $butketName = $attributeCode . '_bucket'; $queryName = $attributeCode . '_query'; if (empty($result[$requestName]['queries'][$queryName])) { $result[$requestName]['queries'][$requestName]['queryReference'][] = [ 'clause' => 'must', 'ref' => $queryName ]; $result[$requestName]['queries'][$queryName] = [ 'name' => $queryName, 'type' => 'filteredQuery', 'filterReference' => [ [ 'clause' => 'must', 'ref' => $filterName ] ] ]; $result[$requestName]['filters'][$filterName] = [ 'name' => $filterName, 'field' => $attributeCode, 'value' => '$'.$attributeCode.'$', 'type' => 'termFilter' ]; $result[$requestName]['aggregations'][$butketName] = [ 'name' => $butketName, 'field' => $attributeCode, 'type' => 'termBucket', 'metric' => [ [ 'type' => 'count' ] ] ]; } } } return $result; }
The problem was solved by replacing the plugin with the search_request.xml file with the code
<?xml version="1.0"?> <!-- /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ --> <requests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Search/etc/search_request.xsd"> <request query="catalog_view_container" index="catalogsearch_fulltext"> <dimensions> <dimension name="scope" value="default"/> </dimensions> <queries> <query xsi:type="boolQuery" name="catalog_view_container" boost="1"> <queryReference clause="must" ref="vendor_stock_status_query"/> </query> <query xsi:type="filteredQuery" name="vendor_stock_status_query"> <filterReference clause="must" ref="vendor_stock_status_filter" /> </query> </queries> <filters> <filter xsi:type="termFilter" name="vendor_stock_status_filter" field="vendor_stock_status" value="$vendor_stock_status$"/> </filters> <aggregations> <bucket name="vendor_stock_status_bucket" field="vendor_stock_status" xsi:type="termBucket"> <metrics> <metric type="count"/> </metrics> </bucket> </aggregations> <from>0</from> <size>10000</size> </request> <request query="quick_search_container" index="catalogsearch_fulltext"> <dimensions> <dimension name="scope" value="default"/> </dimensions> <queries> <query xsi:type="boolQuery" name="quick_search_container" boost="1"> <queryReference clause="must" ref="vendor_stock_status_query"/> </query> <query xsi:type="filteredQuery" name="vendor_stock_status_query"> <filterReference clause="must" ref="vendor_stock_status_filter" /> </query> </queries> <filters> <filter xsi:type="termFilter" name="vendor_stock_status_filter" field="vendor_stock_status" value="$vendor_stock_status$"/> </filters> <aggregations> <bucket name="vendor_stock_status_bucket" field="vendor_stock_status" xsi:type="termBucket"> <metrics> <metric type="count"/> </metrics> </bucket> </aggregations> <from>0</from> <size>10000</size> </request> </requests>