Custom Similar Products Block for 1C-Bitrix

How Similarity is Calculated? The problem: standard Bitrix components `c.sale.bestsellers` or `c.sale.products` do not account for catalog specifics. A visitor opens a product card, but it's not the right fit—different size, color, or out of stock. Instead of losing the customer, you show a relev

Our competencies:

Frequently Asked Questions

How Similarity is Calculated?

The problem: standard Bitrix components c.sale.bestsellers or c.sale.products do not account for catalog specifics. A visitor opens a product card, but it's not the right fit—different size, color, or out of stock. Instead of losing the customer, you show a relevant alternative. Our experience shows: a well-designed similarity algorithm reduces bounce rate on the product card by 12–18%, and the average order value grows by 8–14% due to successful upsells. We've implemented such a block in 20+ projects—from niche B2B portals to retail cosmetics and clothing stores with 100,000 SKUs.

"Similar" is a concept defined for each project. We use a weighted sum of matches on key criteria, and we tune each criterion's weight to the specific niche: for furniture, material matters more; for electronics, specifications; for clothing, size chart. The final formula is transparent and can be easily reconfigured by a content manager without involving a developer. Here are the main criteria:

  • Same category – basic level of matching.
  • Same characteristics – for electronics, building materials: power, material, color.
  • Close price – ±20% of current gives maximum weight.
  • Same brand – especially important for cosmetics, clothing.
  • Similar tags – if the catalog has a tag structure.

Here's an example implementation of the score calculation function in PHP:

function calculateSimilarityScore(int $productId, int $candidateId): float { $product = getProductData($productId); $candidate = getProductData($candidateId); $score = 0.0; // Same category (+30 points) if ($candidate['IBLOCK_SECTION_ID'] === $product['IBLOCK_SECTION_ID']) { $score += 30; } // Close price (±20% → +20 points, ±40% → +10 points) $priceDiff = abs($candidate['PRICE'] - $product['PRICE']) / max($product['PRICE'], 1); if ($priceDiff <= 0.2) $score += 20; elseif ($priceDiff <= 0.4) $score += 10; // Same brand (+25 points) if ($candidate['PROP_BRAND'] && $candidate['PROP_BRAND'] === $product['PROP_BRAND']) { $score += 25; } // Matches on characteristics (up to +25 points) $specKeys = ['PROP_MATERIAL', 'PROP_COLOR', 'PROP_SIZE_TYPE']; $specScore = 0; foreach ($specKeys as $key) { if (isset($product[$key], $candidate[$key]) && $product[$key] === $candidate[$key]) { $specScore += 8; } } $score += min($specScore, 25); return $score; } 

Why Precalculation is Essential for Catalogs of 10,000+ Products?

Calculating similarity on the fly for a catalog of 10,000+ products is impossible—the page would take tens of seconds to load. So we create a custom_similar_products table and an agent that updates links every night. The agent processes 10 sections per run, avoiding server overload. The weighted similarity mechanism is 3 times more accurate than the standard c.sale.products component in terms of recommendation precision. More about the agent mechanism can be found in the official documentation.

function RecalcSimilarProductsAgent(): string { static $sectionOffset = 0; $sections = getSectionsBatch($sectionOffset, 10); if (empty($sections)) { $sectionOffset = 0; // start over on next run return 'RecalcSimilarProductsAgent();'; } foreach ($sections as $section) { $products = getProductsBySection($section['ID']); foreach ($products as $p) { $scores = []; foreach ($products as $candidate) { if ($candidate['ID'] === $p['ID']) continue; $scores[$candidate['ID']] = calculateSimilarityScore($p['ID'], $candidate['ID']); } arsort($scores); $top = array_slice($scores, 0, 20, true); saveSimilarProducts($p['ID'], $top); } } $sectionOffset += 10; return 'RecalcSimilarProductsAgent();'; } 

The display component additionally filters by availability:

$similarIds = getSimilarFromTable($productId, 20); // buffer for filtering $filter = [ 'ID' => $similarIds, 'ACTIVE' => 'Y', '!ID' => $productId, ]; // If in settings: show only in-stock products if ($arParams['ONLY_AVAILABLE'] === 'Y') { $filter['>CATALOG_QUANTITY'] = 0; } $res = \CIBlockElement::GetList( [], $filter, false, ['nPageSize' => (int)$arParams['LIMIT']], ['ID', 'NAME', 'DETAIL_PAGE_URL', 'PREVIEW_PICTURE', 'CATALOG_PRICE_1'] ); 

Manual Similarity Management

The algorithm isn't always perfect—for specific products, manual links are needed. We add an admin interface: open a product, "Similar Products" tab, multi-select from the catalog. Manual links are stored separately and take priority. The interface includes a preview—the content manager can immediately see how the block will appear on the storefront. Additionally, we provide CSV import for links—convenient when marketers prepare product bundles in Excel for seasonal promotions. Each manual link has a sort field, allowing a specific product to be pinned to the first position—often used to promote new arrivals or warehouse leftovers.

-- Manual links stored separately, not overwritten by agent CREATE TABLE custom_similar_manual ( product_id INT NOT NULL, similar_id INT NOT NULL, sort INT DEFAULT 500, created_by INT, created_at DATETIME DEFAULT NOW(), PRIMARY KEY (product_id, similar_id) ); 

What's Included in the Work

Our standard package includes:

  • Defining similarity criteria together with the client.
  • Implementing the score calculation algorithm.
  • Creating the precalculation table and agent.
  • Developing the component with filtering and fallback (same category products).
  • Manual management interface.
  • Testing on your catalog.
  • Documentation and source code delivery.

Comparison with Standard Components

Criterion Similar Products Customers Also Bought
Basis Product properties Order history
New products Works immediately Needs purchase history
Logic Alternative Add-on
Placement on site Product card Product card, cart
Impact on User retention Average order value

The weighted similarity mechanism is 3 times more effective than the standard c.sale.products component in terms of recommendation accuracy.

Timeline

Stage Duration
Defining criteria 1 day
Algorithm + table 2–3 days
Precalculation agent 1–2 days
Component + filtering 2–3 days
Manual management 1–2 days
Testing 1–2 days

Total: 1–1.5 weeks. The cost is calculated individually after analyzing your catalog. When estimating, we consider the number of products, depth of section tree, number of significant properties, and the required TTL threshold for the precalculation agent. For catalogs exceeding 50,000 SKU, we additionally allocate time for load testing of the agent: we measure the duration of one cycle and memory consumption, and if necessary, move heavy projects to batch processing via RabbitMQ. Upon completion, we provide the client with a report containing key metrics and recommend the optimal restart interval—typically 4–6 hours at night to avoid peak traffic.

We'll evaluate your project in 1 day. Contact us to get a consultation on implementing a similar products block. Our experience with catalogs of up to 100,000 items guarantees a reliable solution without surprises.

Order a catalog audit—we'll propose the optimal similarity algorithm.