Rating and Review Filter Development for 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Showing 1 of 1All 1626 services
Rating and Review Filter Development for 1C-Bitrix
Medium
~1-2 weeks
Frequently Asked Questions

Our competencies:

Development stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1356
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    943
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    693
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    828
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    731
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    1073

Rating and Review Filter Development for 1C-Bitrix

You run a catalog with tens of thousands of products and reviews. Clients want to filter products with a rating of 4.5 stars or higher, or only those that have reviews. The standard 1C-Bitrix smart filter cannot handle this — it only works with information block properties and price, whereas rating is a computed value stored in third-party tables (blog, vote, custom). Without proper implementation, each query with a JOIN adds 0.5–1.5 seconds to page load time. We are a team with over 5 years of commercial development experience, having implemented more than 50 projects, including catalogs with thousands of products. UF-fields are a proven method that provides filtering without JOINs and without rewriting the standard component. Let us show how it works in practice.

Why does the smart filter not see the rating?

Because it does not know about the UF_RATING and UF_REVIEW_COUNT fields. The filtering system only works with information block properties, while UF-fields are properties of other entities. However, if you add these UF-fields to the information block element (via ENTITY_ID='IBLOCK_ELEMENT'), the smart filter will start seeing and using them. This eliminates the need to override the component or write custom queries.

How to add UF-fields for rating filtering?

We use a combination of UF-fields plus an event handler or agent. This provides high performance (filtering without JOINs) and flexibility (filter by any range).

Structure of UF-fields for rating

// Создание UF-полей при установке
$userTypeManager = \Bitrix\Main\EventManager::getInstance();

// UF_RATING - средний рейтинг
\CUserTypeEntity::Add([
    'ENTITY_ID'    => 'IBLOCK_' . CATALOG_IBLOCK_ID . '_SECTION',
    'FIELD_NAME'   => 'UF_RATING',
    'USER_TYPE_ID' => 'double',
    'MANDATORY'    => 'N',
    'SHOW_FILTER'  => 'S',
    'SETTINGS'     => ['PRECISION' => 1, 'MIN' => 0, 'MAX' => 5],
]);

// UF_REVIEW_COUNT - количество отзывов
\CUserTypeEntity::Add([
    'ENTITY_ID'    => 'IBLOCK_' . CATALOG_IBLOCK_ID . '_SECTION',
    'FIELD_NAME'   => 'UF_REVIEW_COUNT',
    'USER_TYPE_ID' => 'integer',
    'MANDATORY'    => 'N',
    'SHOW_FILTER'  => 'S',
]);

Update rating when a review is added

AddEventHandler('blog', 'OnAfterPostAdd', 'updateProductRating');
AddEventHandler('blog', 'OnAfterPostUpdate', 'updateProductRating');

function updateProductRating($id, $fields)
{
    // Получение ID товара из связи с отзывом
    $productId = getProductIdFromPost($id);
    if (!$productId) return;

    // Пересчёт рейтинга
    $reviews = getProductReviews($productId);
    $count = count($reviews);
    $avg = $count > 0
        ? array_sum(array_column($reviews, 'rating')) / $count
        : 0;

    // Обновление UF-полей элемента
    CIBlockElement::SetPropertyValues($productId, CATALOG_IBLOCK_ID, [
        'UF_RATING'       => round($avg, 1),
        'UF_REVIEW_COUNT' => $count,
    ]);
}

Filter by minimum rating

// Применение фильтра рейтинга
if (!empty($_GET['min_rating'])) {
    $minRating = floatval($_GET['min_rating']);
    if ($minRating >= 1 && $minRating <= 5) {
        $arFilter['>=UF_RATING'] = $minRating;
    }
}

// Фильтр "только с отзывами"
if (!empty($_GET['has_reviews'])) {
    $arFilter['>UF_REVIEW_COUNT'] = 0;
}

UI: star rating filter

$currentMinRating = floatval($_GET['min_rating'] ?? 0);
?>
<div class="filter-block filter-block--rating">
    <h3 class="filter-block__title">Рейтинг</h3>
    <div class="rating-filter">
        <?php for ($stars = 5; $stars >= 1; $stars--): ?>
        <label class="rating-option <?= $currentMinRating == $stars ? 'is-active' : '' ?>">
            <input type="radio" name="min_rating"
                   value="<?= $stars ?>"
                   <?= $currentMinRating == $stars ? 'checked' : '' ?>>
            <span class="stars">
                <?php for ($i = 1; $i <= 5; $i++): ?>
                <svg class="star <?= $i <= $stars ? 'star--filled' : 'star--empty' ?>"
                     viewBox="0 0 24 24" width="16" height="16">
                    <polygon points="12,2 15.09,8.26 22,9.27 17,14.14 18.18,21.02 12,17.77 5.82,21.02 7,14.14 2,9.27 8.91,8.26"/>
                </svg>
                <?php endfor; ?>
                <span class="stars-label">от <?= $stars ?></span>
            </span>
        </label>
        <?php endfor; ?>
    </div>

    <label class="filter-toggle">
        <input type="checkbox" name="has_reviews" value="1"
               <?= !empty($_GET['has_reviews']) ? 'checked' : '' ?>>
        <span>Только с отзывами</span>
    </label>
</div>
<?php

Sort by rating

Rating filtering combines naturally with sorting:

$sortField = htmlspecialchars($_GET['sort'] ?? 'SORT');
$sortOrder = in_array(strtoupper($_GET['order'] ?? 'ASC'), ['ASC', 'DESC'])
    ? strtoupper($_GET['order'])
    : 'ASC';

$arSort = match ($sortField) {
    'rating'  => ['UF_RATING' => 'DESC'],
    'reviews' => ['UF_REVIEW_COUNT' => 'DESC'],
    'price'   => ['CATALOG_PRICE_1' => $sortOrder],
    default   => ['SORT' => 'ASC'],
};

Why are UF-fields faster than JOIN?

UF-fields are stored in separate tables with indexes and do not require computational operations for filtering. Unlike JOINs, where each query merges tables, filtering by UF-fields executes in constant time. Compare:

Approach Filtering time (15,000 products) Implementation complexity Configuration flexibility
UF-fields with index 0.2 sec Medium High (any ranges)
JOIN to custom table 1.5 sec High Medium (exact match only)
Standard smart filter Not possible

According to the 1C-Bitrix official guide on user fields, UF-fields can participate in filtering when SHOW_FILTER = 'S' is set. See also the Wikipedia article on 1C-Bitrix for general platform information.

Step-by-step implementation of rating filtering

  1. Create UF-fields. Add UF_RATING (double) and UF_REVIEW_COUNT (integer) with SHOW_FILTER='S'.
  2. Develop an event handler. In the OnAfterPostAdd handler, recalculate the average rating and review count.
  3. Configure the filter in the component. Specify the FILTER_NAME parameter and use UF-fields in the filter.
  4. Build the UI filter. Create a star interface with radio buttons for minimum rating.
  5. Add sorting. Include sorting options by UF_RATING and UF_REVIEW_COUNT.

Comparison of rating update methods

Method Performance Complexity When to use
Event handler (OnAfterPostAdd) High (instant) Medium Reviews are published immediately
Periodic agent (every 30 min) Medium (deferred) Low Reviews go through moderation
Manual recalculation Low (on demand) Low Few reviews, testing

Case study: electronics marketplace

One of our clients is an electronics online store with 15,000 products. We implemented a star rating filter and sorting by rating. UF-fields are updated via an agent every 30 minutes (not by event, because reviews go through moderation). After moderation, manual recalculation via a button in the admin panel. Result: products without reviews (new items) are hidden by default in the filter, shown when the "Only with reviews" checkbox is unchecked. The conversion rate from the filtered catalog (rating 4+) is 23% higher than average. The project was delivered on time, the client is satisfied — we guarantee reliability and post-launch support.

Common implementation mistakes

  • Forgetting to set SHOW_FILTER='S' — without this, UF-fields do not participate in filtering.
  • Not indexing UF-fields — performance drops on large catalogs.
  • Using exact match instead of range — rating is rarely an integer.
  • Not updating the rating when a review is deleted — data becomes stale.

What is included in the work

  • Creation of UF-fields and index setup.
  • Development of an event handler or agent for rating recalculation.
  • Frontend of a star UI filter with responsiveness.
  • Sort by rating and reviews.
  • Cache optimization for high load.
  • Documentation and brief training for administrators.
  • Access to code repository and deployment instructions.
  • Post-launch support for 1 month.

Timeline and cost

A filter based on UF-fields with a simple UI — from 1 business day (starting at $200). Full implementation with rating recalculation, star UI, sorting, and an agent — 2–3 business days (typically $500–$800). Cost is calculated individually after analyzing your project.

Contact us for a free assessment of your project. Request development — get a consultation on the optimal solution for your catalog.

Learn more about the capabilities of UF-fields in the official 1C-Bitrix documentation. And general information about the platform on Wikipedia.

1C-Bitrix Catalog Development: How to Transform a 4-Second Filter into Instant Response

In an online store with 80,000 products, the smart filter on Bitrix is sluggish — every click on a property turns into a 4-second wait. The customer clicks the 'Apple brand' checkbox, watches the spinning loader, and leaves for competitors. Conversion drops by 20%. This is a familiar pain. We specialize in 1C-Bitrix catalog development and filtering: we design architectures that handle half a million items without degradation — through faceted indexes, proper storage selection, and tagged caching. If your store is losing money due to a slow filter — order an audit of the current architecture, and we'll assess the problem in one day.

How Do Information Blocks Affect Catalog Performance?

Information blocks are the foundation of the catalog, but on projects with tens of thousands of products, they become a bottleneck. The standard bitrix:catalog.smart.filter generates JOINs on 6–8 property tables (b_iblock_element_property), leading MySQL into a full scan. We change the approach: during design, we determine which properties go into the information block and which into Highload blocks. For reference data (brands, cities, size charts) we use HLB: they work with a separate table without the overhead of b_iblock_element_property. When a 'Cities' dropdown loads for 8 seconds due to 5000 values — that's a signal to move them to HLB. A catalog of 80,000 products with a 4-second filter loses significant revenue annually due to customer attrition — the right architecture delivers that kind of savings. Contact us to estimate the benefit for your project.

What Is the Faceted Index and Why Is It Important?

The core performance lies here. Without a faceted index, every filter click is an SQL query with JOINs on b_iblock_element, b_iblock_element_property, b_catalog_price, and a few more tables. On 100,000 products, such a query takes 2–4 seconds. With a faceted index — 30–80 ms. According to official documentation, the faceted index reduces query execution time by tens of times (in real projects — up to 50 times). The mechanism: 1C-Bitrix creates a table b_catalog_smart_filter where it stores pre-calculated combinations of 'section + property + value + product count'. When filtering, the engine accesses this flat table instead of collecting data from the normalized structure of information blocks.

Common mistakes when configuring the faceted index include not creating the index for all sections, forgetting to set up background reindexing after bulk imports — causing property counters to mismatch the actual product count. Including all properties in the facet, even service ones, bloats the b_catalog_smart_filter table. On catalogs with over 300,000 items, its size can exceed a gigabyte — monitoring via SHOW TABLE STATUS LIKE 'b_catalog_smart_filter' is essential. Conclusion: the faceted index provides radical acceleration, but requires careful configuration and automatic reindexing via the agent CIBlockCatalog::ReindexFacet or cron.

Why Are Highload Blocks Faster Than Information Blocks for Reference Data?

Criterion Information Block (IB) Highload Block (HLB)
Property storage b_iblock_element_property table Separate flat table per HLB
Filter speed on 50k products ~500–800 ms (with facet) ~80–150 ms (without facet)
SEO support (URL, templates) Full None (only reference data)
Recommended for Products, sections, main properties Reference data (brands, cities), custom data
When Information Blocks Are Preferred Over HLBHighload blocks do not generate SEO-friendly URLs and lack a visual editor. If the reference data requires separate pages (e.g., brands with unique H1s), use information blocks. HLB is strictly for service data that does not need indexing.

In practice, the best architecture is hybrid. Products and sections live in information blocks — there you have SEO, visual editor, and standard catalog components. Reference properties with thousands of values are moved to Highload blocks. User data (favorites, viewed items, comparisons) also go to HLB — they grow quickly, and information blocks are not designed for that. Want to know which architecture to choose for your catalog? Contact us — we'll analyze your data structure and provide recommendations.

SEO Filters: How to Get SEO-Friendly URLs and Not Get Penalized by Yandex?

The standard filter generates ?filter[brand]=apple&filter[color]=black — search engines either do not index such URLs or consider them duplicates. But the query 'black apple laptops' is the most converting low-frequency traffic. We create SEO-friendly URLs: /catalog/laptops/brand-apple/color-black/ with unique title, description, and H1. Not template-based 'Buy {brand} in Minsk', but meaningful ones reflecting the specific combination.

  • Canonical URLs — to prevent /brand-apple/color-black/ and /color-black/brand-apple/ from duplicating.
  • Control of the number of indexed combinations — 10 properties with 20 values each yield millions of pages; Yandex penalizes that.
  • Automatic sitemap for SEO filter pages.
  • Admin interface for the manager — they decide which intersections to index.

Order the implementation of SEO filters — get a ready-made tool for attracting low-frequency traffic with conversion growth up to 30%.

What Methods Provide a Significant Performance Boost?

  • Fetching only necessary fields via arSelect — no SELECT * on information blocks.
  • Managed tag-based caching: when a product is added, the cache is automatically rebuilt.
  • Composite cache for anonymous users: TTFB < 100 ms, HTML is served without running PHP.
  • Indexes on properties used in filtering — without them MySQL scans the entire b_iblock_element_property table.
  • TTFB monitoring: if the catalog responds slower than 500 ms, we check the slow query log.

What Is Included in Comprehensive Catalog Development on 1C-Bitrix

We deliver not just working code, but a complete set of documentation and tools for independent management. Deliverables include:

  • Audit of current catalog and filtering architecture.
  • Project documentation describing data schema, distribution across information blocks and Highload blocks, and facet composition.
  • Ready smart filter with AJAX mode, grouping, and state persistence.
  • Configured faceted index with cron reindexing.
  • SEO filters with SEO-friendly URLs, unique meta tags, canonicals, and sitemap.
  • Integration of quick view and sorting (AJAX, mobile adaptation).
  • Operational documentation for managers: how to add properties, manage indexes and SEO combinations.
  • 30-day warranty support after delivery — we fix incidents and answer questions.

How We Develop a Catalog: Step-by-Step Plan

We don't just install components. The process includes:

  1. Audit of the current catalog — analysis of property structure, identification of bottlenecks, checking indexes and cache.
  2. Architecture design — data distribution between information blocks and HLB, determining facet composition.
  3. Development of the smart filter — template customization, AJAX mode, grouping, state persistence.
  4. Faceted index configuration — creation, cron reindexing, monitoring.
  5. SEO filters — SEO-friendly URLs, meta tags, canonicals, sitemap.
  6. Integration of quick view and sorting — AJAX modal with photo, price, availability, preload on hover. On mobile — bottom sheet instead of popup.
  7. Manager training — how to manage properties, indexes, and SEO combinations.
  8. Warranty support — 30 days after delivery.

Implementation Timeline

Task Estimated Duration
Smart filter configuration 3–5 days
Faceted search 2–3 days
SEO filters 1–2 weeks
Quick view 3–5 days
Custom catalog template 1–2 weeks
Migration to Highload blocks 2–4 weeks
Comprehensive catalog development 4–8 weeks

The catalog pays off through conversion growth and an influx of SEO traffic from low-frequency queries. The customer finds the product in two clicks, rather than leaving after the first click on the filter. Get a consultation — we will evaluate your project within a day and provide a project plan and roadmap for 1C-Bitrix catalog development. Contact us through the form on the website — certified specialists with over 200 successful projects.