Skip to content

Commit 0c1cead

Browse files
authored
ENGCOM-6388: Fix SearchResult isCacheable performance #25851
2 parents a1d3605 + c248dfa commit 0c1cead

File tree

3 files changed

+77
-60
lines changed

3 files changed

+77
-60
lines changed

app/code/Magento/Search/Model/PopularSearchTerms.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace Magento\Search\Model;
88

99
/**
10-
* Popular search terms
10+
* Finds top search results in search
1111
*/
1212
class PopularSearchTerms
1313
{
@@ -29,7 +29,7 @@ class PopularSearchTerms
2929

3030
/**
3131
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
32-
* @param \Magento\Search\Model\ResourceModel\Query\Collection
32+
* @param \Magento\Search\Model\ResourceModel\Query\Collection $queryCollection
3333
*/
3434
public function __construct(
3535
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
@@ -48,13 +48,8 @@ public function __construct(
4848
*/
4949
public function isCacheable(string $term, int $storeId)
5050
{
51-
$terms = $this->queryCollection
52-
->setPopularQueryFilter($storeId)
53-
->setPageSize($this->getMaxCountCacheableSearchTerms($storeId))
54-
->load()
55-
->getColumnValues('query_text');
56-
57-
return in_array($term, $terms);
51+
$maxCountCacheableSearchTerms = $this->getMaxCountCacheableSearchTerms($storeId);
52+
return $this->queryCollection->isTopSearchResult($term, $storeId, $maxCountCacheableSearchTerms);
5853
}
5954

6055
/**

app/code/Magento/Search/Model/ResourceModel/Query/Collection.php

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,25 @@
55
*/
66
namespace Magento\Search\Model\ResourceModel\Query;
77

8+
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
9+
use Magento\Framework\Data\Collection\EntityFactoryInterface;
10+
use Magento\Framework\DB\Adapter\AdapterInterface;
11+
use Magento\Framework\DB\Helper;
12+
use Magento\Framework\Event\ManagerInterface;
13+
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
14+
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
815
use Magento\Store\Model\Store;
16+
use Magento\Store\Model\StoreManagerInterface;
17+
use Psr\Log\LoggerInterface;
918

1019
/**
1120
* Search query collection
1221
*
1322
* @api
1423
* @since 100.0.2
24+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1525
*/
16-
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
26+
class Collection extends AbstractCollection
1727
{
1828
/**
1929
* Store for filter
@@ -25,36 +35,38 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
2535
/**
2636
* Store manager
2737
*
28-
* @var \Magento\Store\Model\StoreManagerInterface
38+
* @var StoreManagerInterface
2939
*/
3040
protected $_storeManager;
3141

3242
/**
3343
* Search resource helper
3444
*
35-
* @var \Magento\Framework\DB\Helper
45+
* @var Helper
3646
*/
3747
protected $_resourceHelper;
3848

3949
/**
40-
* @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
41-
* @param \Psr\Log\LoggerInterface $logger
42-
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
43-
* @param \Magento\Framework\Event\ManagerInterface $eventManager
44-
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
45-
* @param \Magento\Framework\DB\Helper $resourceHelper
46-
* @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
47-
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
50+
* Constructor
51+
*
52+
* @param EntityFactoryInterface $entityFactory
53+
* @param LoggerInterface $logger
54+
* @param FetchStrategyInterface $fetchStrategy
55+
* @param ManagerInterface $eventManager
56+
* @param StoreManagerInterface $storeManager
57+
* @param Helper $resourceHelper
58+
* @param AdapterInterface $connection
59+
* @param AbstractDb $resource
4860
*/
4961
public function __construct(
50-
\Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
51-
\Psr\Log\LoggerInterface $logger,
52-
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
53-
\Magento\Framework\Event\ManagerInterface $eventManager,
54-
\Magento\Store\Model\StoreManagerInterface $storeManager,
55-
\Magento\Framework\DB\Helper $resourceHelper,
56-
\Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
57-
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
62+
EntityFactoryInterface $entityFactory,
63+
LoggerInterface $logger,
64+
FetchStrategyInterface $fetchStrategy,
65+
ManagerInterface $eventManager,
66+
StoreManagerInterface $storeManager,
67+
Helper $resourceHelper,
68+
AdapterInterface $connection = null,
69+
AbstractDb $resource = null
5870
) {
5971
$this->_storeManager = $storeManager;
6072
$this->_resourceHelper = $resourceHelper;
@@ -149,6 +161,36 @@ public function setPopularQueryFilter($storeIds = null)
149161
return $this;
150162
}
151163

164+
/**
165+
* Determines whether a Search Term belongs to the top results for given storeId
166+
*
167+
* @param string $term
168+
* @param int $storeId
169+
* @param int $maxCountCacheableSearchTerms
170+
* @return bool
171+
*/
172+
public function isTopSearchResult(string $term, int $storeId, int $maxCountCacheableSearchTerms):bool
173+
{
174+
$select = $this->getSelect();
175+
$select->reset(\Magento\Framework\DB\Select::FROM);
176+
$select->reset(\Magento\Framework\DB\Select::COLUMNS);
177+
$select->distinct(true);
178+
$select->from(['main_table' => $this->getTable('search_query')], ['query_text']);
179+
$select->where('main_table.store_id IN (?)', $storeId);
180+
$select->where('num_results > 0');
181+
$select->order(['popularity desc']);
182+
183+
$select->limit($maxCountCacheableSearchTerms);
184+
185+
$subQuery = new \Zend_Db_Expr('(' . $select->assemble() . ')');
186+
187+
$select->reset();
188+
$select->from(['result' => $subQuery ], []);
189+
$select->where('result.query_text = ?', $term);
190+
191+
return $this->getSize() > 0;
192+
}
193+
152194
/**
153195
* Set Recent Queries Order
154196
*

app/code/Magento/Search/Test/Unit/Model/PopularSearchTermsTest.php

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,47 +49,27 @@ protected function setUp()
4949
/**
5050
* Test isCacheableDataProvider method
5151
*
52-
* @dataProvider isCacheableDataProvider
53-
*
54-
* @param string $term
55-
* @param array $terms
56-
* @param $expected $terms
57-
*
5852
* @return void
5953
*/
60-
public function testIsCacheable($term, $terms, $expected)
54+
public function testIsCacheable()
6155
{
62-
$storeId = 7;
63-
$pageSize = 25;
56+
$term = 'test1';
57+
$storeId = 1;
58+
$pageSize = 35;
6459

65-
$this->scopeConfigMock->expects($this->once())->method('getValue')
60+
$this->scopeConfigMock->expects($this->exactly(2))
61+
->method('getValue')
6662
->with(
6763
PopularSearchTerms::XML_PATH_MAX_COUNT_CACHEABLE_SEARCH_TERMS,
6864
ScopeInterface::SCOPE_STORE,
6965
$storeId
7066
)->willReturn($pageSize);
71-
$this->queryCollectionMock->expects($this->once())->method('setPopularQueryFilter')->with($storeId)
72-
->willReturnSelf();
73-
$this->queryCollectionMock->expects($this->once())->method('setPageSize')->with($pageSize)
74-
->willReturnSelf();
75-
$this->queryCollectionMock->expects($this->once())->method('load')->willReturnSelf();
76-
$this->queryCollectionMock->expects($this->once())->method('getColumnValues')->with('query_text')
77-
->willReturn($terms);
78-
79-
$actual = $this->popularSearchTerms->isCacheable($term, $storeId);
80-
self::assertEquals($expected, $actual);
81-
}
67+
$this->queryCollectionMock->expects($this->exactly(2))
68+
->method('isTopSearchResult')
69+
->with($term, $storeId, $pageSize)
70+
->willReturn(true, false);
8271

83-
/**
84-
* @return array
85-
*/
86-
public function isCacheableDataProvider()
87-
{
88-
return [
89-
['test01', [], false],
90-
['test02', ['test01', 'test02'], true],
91-
['test03', ['test01', 'test02'], false],
92-
['test04', ['test04'], true],
93-
];
72+
$this->assertTrue($this->popularSearchTerms->isCacheable($term, $storeId));
73+
$this->assertFalse($this->popularSearchTerms->isCacheable($term, $storeId));
9474
}
9575
}

0 commit comments

Comments
 (0)