Affiliate feed pipeline: Jak párovat 50 000 produktů přes EAN — případovka FMAN.cz

4 minuty čtení

FMAN.cz má 3 600 produktů z 12 e-shopů, Zveráč.cz dokonce 53 000 z 8 partnerů. Klíč k tomu, že to není zoo duplikátů a nesmyslů: feed pipeline s automatickým párováním přes EAN. V tomto článku detailně rozeberu, jak ji postavit — od stahování XML feedů po deduplikaci a monitoring.

Co se v tomto článku dozvíte

  • Architektura feed pipeline (5 fází)
  • EAN matching strategy (90 % automatický match)
  • Fuzzy matching když EAN chybí (Levenshtein, brand normalization)
  • Monitoring + alerting pro feedy
  • Časté chyby (drahé z hlediska SEO i UX)

Architektura feed pipeline (5 fází)

Fáze 1: Stahování (Fetcher)

  • Cron 1× denně (00:30 noční hodiny)
  • Per e-shop konfigurace (URL, auth method, retry policy)
  • Streaming download (XML stream parser, ne load celý do paměti)
  • Validation: kontrola, že feed má min. 50 % původní velikosti

Fáze 2: Parsing (Parser)

  • XML / CSV / JSON adaptery per format
  • Ukládá do staging tabulky (raw_offers)
  • Žádné ověření vůči existující DB ještě
  • Pole: source_id, sku, ean, name, price, url, image, brand, category

Fáze 3: Normalizace (Normalizer)

  • Brand normalize (Royal Canin / RoyalCanin / Royal-Canin → ROYAL_CANIN)
  • Category mapping (per e-shop dictionary → unifikovaná taxonomie)
  • Cena s DPH check (E-shop A bez DPH, E-shop B s DPH)
  • HTML sanitization (popis bez tracking pixelů a iframe)
  • Image download + WebP conversion

Fáze 4: Matching (Matcher)

Klíčová fáze. 4 strategie v pořadí:

  1. EAN match — 90 % case
  2. MPN + brand fallback — 5 % případů
  3. Fuzzy name match (Levenshtein dist < 10) + brand + category — 3 %
  4. Manuální review queue — 2 %

Fáze 5: Persistence (Writer)

  • Batch insert / update do products + offers
  • Trigger na materialized view refresh
  • Search index update (pokud používáte Algolia / Meilisearch)
  • Sitemap regeneration

EAN matching deep dive

EAN (European Article Number) = 13-digit code unikátní per produkt. Funguje pro 90 % FMCG produktů.

Pseudokód

function matchProduct(rawOffer):
  if rawOffer.ean and len(rawOffer.ean) == 13:
    existing = Product.findByEan(rawOffer.ean)
    if existing:
      return existing
    else:
      return Product.create(from_offer=rawOffer)
  else:
    return fuzzyMatch(rawOffer)

Edge cases

  • Variant produkty (velikost, barva) — stejný EAN per variant. Řešení: SKU jako secondary key.
  • EAN typo — checksum validation (poslední číslice je hash předchozích 12).
  • Bundle produkty (set 3 ks) — separátní EAN, často chybí. Řešení: ručně.
  • Generic items (bezznačkové, např. „bavlněné tričko XL“) — chybí EAN. Fuzzy match.

Fuzzy matching když EAN chybí

Pro 10 % produktů bez EAN je nutný fuzzy match. Algoritmus:

  1. Brand match (musí být stejný brand)
  2. Category match (musí být ve stejné kategorii)
  3. Name similarity (Levenshtein distance < 10 z 50 znaků)
  4. Confidence score > 0.85

Pod confidence 0.85 jde do review queue (admin schvaluje manuálně).

Monitoring + alerting

MetrikaThreshold alert
Feed not fetched 24 hCritical
Product count drop > 10 %Warning
Match rate < 80 %Warning
Manual review queue > 100Info
Fetcher error rate > 5 %Critical

Alert kanály: Slack, email, SMS pro Critical.

Reálná data: FMAN.cz pipeline

  • 12 partnerských e-shopů
  • 3 600 unique produktů, ~5 200 nabídek (1 produkt často ve 2+ e-shopech)
  • Daily run: 4 minuty (od fetch po DB write)
  • Match rate: 89 % (10 % manuální review, 1 % skip)
  • Hosting cost: $8/měs (DB) + $5 cron worker
  • Maintenance: 2 hodiny / týden (review queue + adjustments)

Časté chyby

  • Žádný checksum validation EAN. Typo v EAN vytvoří fake produkt.
  • Žádná category dictionary. E-shop A „Mountain Bike“, E-shop B „Horské kolo“ — bez mapování duplicate kategorie.
  • Image hotlink. Linkujete obrázek z partnerova CDN — když ho smaže, váš web má broken image.
  • Žádný retry. Fetcher failne, partner ve feedu chybí 24 hodin.
  • Sync v reálném čase. Daily 4-min batch jobu lepší než real-time webhook spam.

Často kladené otázky

Jak rychlé pipeline pro 50k+ produktů?

Zveráč.cz: 53 000 produktů, daily run 18 minut. Kombinace MySQL bulk insert (10k rows/batch) + parallelism (4 worker threads).

Funguje to s Heuréka XML feedem?

Ano. Heuréka XML format je standard. Většina českých e-shopů ho exportuje.

Co s real-time změnami cen?

Daily batch je dostatečný pro 95 % use cases. Pro flash sales (Black Friday) doporučuju 4× denně.

Mohu mít fuzzy match s Embedding modelem?

Ano. OpenAI text-embedding-3 nebo Cohere embed-multilingual-v3 dají lepší fuzzy match než Levenshtein. Cena: $0.13/1M tokens — pro 50k produktů ~$2/měs.

Co OutOfStock products?

Označit jako out_of_stock = true, neukazovat v hlavním listu. Po 90 dnech soft delete.

Související články

🎁
ZDARMA

SEO checklist 2026 — 57 bodů

Praktický audit pro malé a střední firmy. Technické SEO + GEO pro AI vyhledávače. PDF okamžitě po zadání emailu.

Stáhnout checklist zdarma