Custom Search Implementation
Custom Search Controller
namespace Vendor\Module\Controller\Search;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Search\Model\QueryFactory;
class Advanced extends Action
{
public function __construct(
Context $context,
private QueryFactory $queryFactory
) {
parent::__construct($context);
}
public function execute()
{
$query = $this->queryFactory->create();
$query->setSearchParam('q', $this->getRequest()->getParam('q'));
$query->setSearchParam('category_id', $this->getRequest()->getParam('category'));
$this->loadLayout();
$this->getLayout()->getChildBlock('search.results')
->setQuery($query);
$this->renderLayout();
}
}
Custom Search Block
namespace Vendor\Module\Block\Search;
use Magento\Search\Block\Result;
class CustomResult extends Result
{
public function getSearchResults(): array
{
$results = parent::getSearchResults();
// Add custom ranking
return $this->rankResults($results);
}
private function rankResults(array $results): array
{
usort($results, function ($a, $b) {
return $b->getRelevance() - $a->getRelevance();
});
return $results;
}
}
Custom Search Collection
namespace Vendor\Module\Model\Search;
class CustomCollection extends \Magento\Search\Model\ResourceModel\Fulltext\Collection
{
public function addSearchFilter($query)
{
// Custom search logic
parent::addSearchFilter($query);
// Add relevance scoring
$this->getSelect()->order('relevance DESC');
return $this;
}
}
Search Customization
Custom Search Result Display
// Template: search/results.phtml
<?php foreach ($block->getSearchResults() as $result): ?>
<div class="search-result">
<h3><a href="<?php echo $result->getProductUrl(); ?>">
<?php echo $result->getName(); ?>
</a></h3>
<p class="price"><?php echo $result->getPrice(); ?></p>
<p class="relevance">Relevance: <?php echo $result->getRelevance(); ?></p>
<?php if ($result->getCustomAttribute()): ?>
<p class="custom"><?php echo $result->getCustomAttribute(); ?></p>
<?php endif; ?>
</div>
<?php endforeach; ?>
Search Filters
// Add custom filters to search
public function addFilters(array $filters)
{
foreach ($filters as $attribute => $value) {
$this->getSelect()->where(
$this->getResource()->getAttribute($attribute)->getAttributeCode() . ' = ?',
$value
);
}
}
Search Sorting
// Custom sort options
public function addSortOrder($sortOrder)
{
switch ($sortOrder) {
case 'relevance':
$this->getSelect()->order('relevance DESC');
break;
case 'price_asc':
$this->getSelect()->order('price ASC');
break;
case 'price_desc':
$this->getSelect()->order('price DESC');
break;
case 'name':
$this->getSelect()->order('name ASC');
break;
}
}
Relevance Tuning
Relevance Scoring
// Custom relevance calculation
public function calculateRelevance($product, $query)
{
$score = 0;
// Exact name match: highest weight
if (stripos($product->getName(), $query) !== false) {
$score += 100;
}
// SKU match
if (stripos($product->getSku(), $query) !== false) {
$score += 90;
}
// Description match
if (stripos($product->getDescription(), $query) !== false) {
$score += 50;
}
// Boost in-stock products
if ($product->isSalable()) {
$score += 20;
}
// Boost by sales
$score += $product->getSalesCount() / 10;
return $score;
}
Attribute Weight Configuration
// Attribute search weights
'catalog/search' => [
'weight' => [
'name' => 10,
'sku' => 9,
'description' => 5,
'short_description' => 4,
'custom_attribute' => 3
]
]
Elasticsearch Relevance
{
"query": {
"multi_match": {
"query": "laptop",
"fields": ["name^10", "sku^9", "description^5"]
}
}
}
Boosting Strategies
- Exact match boost — exact term matches get highest score
- Field weight — name > SKU > description
- Stock boost — in-stock products ranked higher
- Sales boost — popular products ranked higher
- Recency boost — newer products ranked higher
Advanced Search Features
Faceted Search
// Add facets to search results
public function addFacets()
{
$this->getSelect()->group('category_id');
// Category facet
$this->getSelect()->columns([
'category_count' => new \Zend_Db_Expr('COUNT(DISTINCT category_id)')
]);
}
Search Analytics
// Track search terms
namespace Vendor\Module\Service;
class SearchAnalytics
{
public function trackSearch(string $query, int $resultCount): void
{
$this->resource->getConnection()->insert('search_log', [
'query' => $query,
'result_count' => $resultCount,
'created_at' => date('Y-m-d H:i:s')
]);
}
}
Search API
// REST API for custom search
// GET /rest/V1/search?searchCriteria[request_name]=quick_search&searchCriteria[filterGroups][0][filters][0][field]=q&searchCriteria[filterGroups][0][filters][0][value]=laptop
// GraphQL search
query {
products(search: "laptop") {
items {
name
sku
price { regularPrice { amount { value } } }
}
total_count
}
}
Best Practices
- Tune relevance weights based on analytics
- Use synonyms for common misspellings
- Track zero-result searches for improvement
- Implement search suggestions
- A/B test relevance changes
Practice Problems
Users report irrelevant search results. Analyze and improve search relevance scoring.
Quiz
1. What gives highest relevance in search scoring?
2. How do you customize search result ranking?
3. What is faceted search?
4. Why track zero-result searches?
Flashcards
Question
What gives highest search relevance?
Click to reveal answer
Answer
Exact name match, followed by SKU, then description
Question
What is faceted search?
Click to reveal answer
Answer
Search with category/attribute filters for refined results
Question
How to track search analytics?
Click to reveal answer
Answer
Log search terms, result counts, and zero-result searches
Question
What is relevance tuning?
Click to reveal answer
Answer
Adjusting attribute weights and boost factors to improve search results
Question
How to improve search with synonyms?
Click to reveal answer
Answer
Map related terms together so laptop also finds notebook results
Revision Notes
Key Takeaways
- 1. Custom search uses controllers, blocks, and collections
- 2. Relevance scoring uses attribute weights and boost factors
- 3. Exact name match gets highest relevance score
- 4. Faceted search enables category/attribute filtering
- 5. Track search analytics to identify improvement opportunities
- 6. Use synonyms to expand search coverage
Interview Tips
- • Explain how to implement custom search functionality
- • Describe relevance scoring and tuning strategies
- • Discuss faceted search and filtering
- • Know how to use search analytics for improvement
Cheat Sheet
Custom Search Cheat Sheet
Relevance scoring:
- Exact name: 100
- SKU: 90
- Description: 50
- In-stock: +20
- Sales: +sales/10
Faceted search:
- Category filter
- Attribute filter
- Price range
Analytics:
- Track search terms
- Monitor zero-results
- Analyze click-through
Improvement:
- Tune attribute weights
- Add synonyms
- A/B test changes
- Review analytics