Product Recommendations System for E-Commerce

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1 servicesAll 2065 services
Product Recommendations System for E-Commerce
Complex
~1-2 weeks
FAQ
Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Developing Product Recommendations System for E-commerce

Recommendations — algorithmic engine increasing average check and catalog depth. "Amazon recommends" — not marketing slogan but complex infrastructure with collaborative filtering, behavioral models, ML pipelines. Takes 10–20+ business days depending on approach.

Complexity Levels

Recommendation algorithms by complexity:

Level Approach When To Use
Basic Rule-based (popular, new, discounted) Store launch
Medium Item-based collaborative filtering 10k+ orders in DB
Advanced Matrix factorization (ALS, SVD) 100k+ events
Enterprise Deep learning (two-tower, BERT4Rec) ML infrastructure

For most stores optimal: medium level — collaborative filtering on orders + content signals.

Rule-Based Recommendations

Quick to start, needs no accumulated data:

class PopularityRecommender {
    public function getPopular(int $categoryId, int $limit = 8): Collection {
        return Product::where('category_id', $categoryId)
            ->where('is_active', true)
            ->withCount(['orderItems as sales_count' => fn($q) =>
                $q->whereHas('order', fn($o) =>
                    $o->where('status', 'completed')
                      ->where('created_at', '>=', now()->subDays(30))
                )
            ])
            ->orderByDesc('sales_count')
            ->limit($limit)
            ->get();
    }
}

New users — popular products. Users with history — personalized.

Collaborative Filtering by Orders

"Users who bought this also bought..." — classic item-to-item CF:

CREATE MATERIALIZED VIEW product_cooccurrences AS
SELECT
    oi1.product_id AS product_a,
    oi2.product_id AS product_b,
    COUNT(DISTINCT oi1.order_id) AS cooccurrence_count
FROM order_items oi1
JOIN order_items oi2
    ON oi1.order_id = oi2.order_id
    AND oi1.product_id != oi2.product_id
JOIN orders o ON oi1.order_id = o.id
WHERE o.status = 'completed'
GROUP BY oi1.product_id, oi2.product_id
HAVING COUNT(DISTINCT oi1.order_id) >= 3;

CREATE INDEX idx_cooc_product_a ON product_cooccurrences(product_a, cooccurrence_count DESC);

Update nightly: $schedule->command('db:refresh-cooccurrences')->dailyAt('03:00');

Get recommendations by viewed product:

class CollaborativeRecommender {
    public function getSimilar(int $productId, int $limit = 8): Collection {
        $recommendedIds = DB::table('product_cooccurrences')
            ->where('product_a', $productId)
            ->orderByDesc('cooccurrence_count')
            ->limit($limit)
            ->pluck('product_b');

        return Product::whereIn('id', $recommendedIds)
            ->where('is_active', true)
            ->get();
    }
}

ML Recommendations via Python Service

For advanced level: Python microservice on FastAPI with ALS model:

import implicit
from fastapi import FastAPI

app = FastAPI()
model = implicit.als.AlternatingLeastSquares(factors=64, iterations=20)

@app.get("/recommendations/user/{user_id}")
async def user_recommendations(user_id: int, n: int = 12):
    user_idx = user_id_to_idx.get(user_id)
    if user_idx is None:
        return {"items": get_popular_fallback(n)}

    ids, scores = model.recommend(user_idx, user_item_matrix[user_idx], N=n)
    product_ids = [idx_to_product_id[i] for i in ids]
    return {"items": product_ids, "scores": scores.tolist()}

PHP backend calls service, caches result:

$recommendations = Cache::remember(
    "recs:user:{$userId}",
    1800,
    fn() => Http::timeout(2)->get("{$this->mlServiceUrl}/recommendations/user/{$userId}", ['n' => 12])
                ->throw()
                ->json('items')
);

Fallback on ML unavailable — rule-based.

Event Tracking for Training

Recommendation quality depends on data. Track:

api.post('/events', {
  type: 'product_view',
  product_id: product.id,
  session_id: getSessionId(),
  timestamp: new Date().toISOString(),
});

api.post('/events', { type: 'add_to_cart', product_id, quantity });
// Purchase tracked server-side after order creation
CREATE TABLE recommendation_events (
    id BIGSERIAL PRIMARY KEY,
    event_type VARCHAR(30) NOT NULL,
    user_id BIGINT,
    session_id VARCHAR(64),
    product_id BIGINT,
    metadata JSONB,
    created_at TIMESTAMP DEFAULT NOW()
);

A/B Testing Algorithms

Show different algorithms to different segments:

$algorithm = $user->id % 2 === 0 ? 'collaborative' : 'ml';
$recommendations = $this->recommenderFactory->make($algorithm)->get($user, $product);

event(new RecommendationShown($user, $recommendations, $algorithm, $context));

After 2–4 weeks compare CTR and conversion, pick winner.

Placement

  • Product page: "Bought with this", "Similar products"
  • Cart: "You forgot to add", "Complete your set"
  • Homepage: "Just for you", "Popular"
  • Post-purchase email: "You might like"
  • Empty search: "Try these products"