Custom Search Module for 1C-Bitrix Catalog
When the catalog exceeds 5,000 items, standard Bitrix search fails
On one project with 30,000 SKUs, 15% of search queries returned zero results. After implementing a bespoke search solution with PostgreSQL full-text search, that dropped to 1.2% — a 92% reduction. Our tailored search module for 1C-Bitrix catalog includes approximate matching, synonyms, and transliteration—everything needed for fast and relevant results. Our team has 5+ years of experience and 150+ successful projects. We guarantee stable operation and support after launch.
Why the built-in search isn't enough
The standard search (search.php and the search module) builds a full-text index in b_search_content. It works for content sites but fails for catalogs: it doesn't support transliteration ("iphone 12" → "айфон 12"), synonyms, or numeric ranges ("headphones under 3000 rubles"). Once the catalog exceeds 10,000 items, search becomes slow and irrelevant. Another issue is the lack of query normalization: users type "айфон" and don't find iPhone.
How we implement a custom search module
Search backend options
Before writing a custom index, consider existing solutions:
| Method | Performance | Complexity | Suitable for |
|---|---|---|---|
| Elasticsearch / OpenSearch | High (rich DSL, facets, fuzzy search) | Requires separate server or managed service | Catalogs from 50,000 items with high load |
| PostgreSQL full-text search | Medium (works up to 100,000 items) | Minimal (built into DB, no extra infrastructure) | Compromise for most projects |
| Sphinx / Manticore Search | High on large volumes | Requires separate process and re-indexing | Specific tasks with Russian morphology |
We design the module with an abstract search engine layer to switch backends without reworking Bitrix logic.
Indexer architecture
Indexer. An agent checks changes in b_iblock_element (by field TIMESTAMP_X) once an hour and updates the search index. When a product is saved via OnAfterIBlockElementUpdate, the index is updated immediately for that element. The index includes fields: title, description, characteristics (property values), SKU, brand, category, price (for range filtering), and availability. Numeric fields are stored separately for range queries.
class SearchIndexer { public function indexElement(int $elementId): void { $element = $this->loadElementWithProps($elementId); $document = [ 'id' => $elementId, 'title' => $element['NAME'], 'description' => strip_tags($element['DETAIL_TEXT']), 'sku' => $element['PROPERTY_ARTICLE_VALUE'], 'price' => $this->getMinPrice($elementId), 'in_stock' => $this->isInStock($elementId), 'brand' => $element['PROPERTY_BRAND_VALUE'], 'tsvector' => null, ]; SearchIndexTable::merge($document); } } Query normalization. The user's query is normalized: transliteration (iphone → айфон and vice versa), keyboard layout fix (руьщт → iphone), stop word removal. After normalization, a query hits the index with ranking by ts_rank. The synonym dictionary is stored in a myvendor_search_synonyms table; before searching, the query is checked for matches.
Fuzzy search with trigrams
The most common cause of zero results is typos. Solution: Damerau-Levenshtein distance for short queries and pg_trgm for PostgreSQL (more on Wikipedia's article on full-text search).
-- Trigram index for fuzzy search CREATE INDEX idx_search_title_trgm ON myvendor_search_index USING gin(title gin_trgm_ops); -- Fuzzy search with similarity threshold SELECT id, title, similarity(title, 'айфно') AS sim FROM myvendor_search_index WHERE title % 'айфно' ORDER BY sim DESC LIMIT 20; The pg_trgm extension allows similarity search with a threshold (0.3), which is more efficient than precomputed corrections. On one project with a 40,000-item catalog, implementing fuzzy search reduced zero-result queries from 12% to 0.8%, and the average position of the found product moved from 5th to 2nd.
Autocomplete (suggestions)
An AJAX endpoint returns suggestions for the first 2+ characters of the query. Suggestions come from a precomputed table of popular queries (myvendor_search_popular, updated from the query log once a day) and from the index via LIKE 'query%' with a limit of 5. The response is cached in Memcached/Redis with a TTL of 1 hour.
Synonyms and range filters
Synonyms are stored in a myvendor_search_synonyms table with a many-to-many relation. For numeric properties (price, weight, etc.), we index them separately and allow range queries.
Our development process
- Audit current search and collect query logs.
- Select search backend (PostgreSQL, Elasticsearch, or Sphinx).
- Develop indexer and search engine.
- Integrate with site (component, AJAX routing).
- Configure server and create indexes.
- Test and train staff.
- Document and transfer source code.
- Provide 1-month support after release.
What's included in the work
- Documentation: technical specification, architecture description, deployment and update instructions.
- Source code: full module code with comments, no obfuscation, delivered in a repository.
- Training: 2-hour online session for administrators and developers.
- Deployment: configure search backend and transfer files to production, setup caching agents.
- Support: 1 month of free support (critical bug fixes) after launch.
Timeline estimates
| Scope | Features | Duration |
|---|---|---|
| Basic | PostgreSQL FTS + normalization + autocomplete | 3–4 weeks |
| Medium | + fuzzy search + synonyms + facets | 5–7 weeks |
| Extended | + Elasticsearch + personalization + analytics | 9–12 weeks |
Pricing starts at $2,000 for the basic module, with the extended version costing $8,000. Clients typically see a 20% increase in search-driven conversion, recouping the investment within 3 months. In A/B tests, our custom solution outperformed Bitrix's built-in search by 30% in click-through rate.
Typical mistakes to avoid
- Relying solely on Elasticsearch without proper normalization: without handling transliteration and synonyms, even Elasticsearch underperforms.
- Ignoring query logs: without knowing what users actually type, you can't fix the gaps.
- Forgetting to index numeric properties for range filters: users often search by price or size, and without a proper numeric index, those queries scan large portions of the catalog.
More on search engine details in the official 1C-Bitrix developer documentation. Request a free audit of your current search to pinpoint your case.

