System Design & Methodology
Companion to
01-thesis-proposal.md. Describes the reference implementation you will build and defend.
1. Architecture Overview
┌──────────────────────────┐
│ E-commerce App │
└────────────┬─────────────┘
│ search(q)
▼
┌─────────────────────────────────────┐
│ Search Gateway │
│ (auth, rate-limit, response cache) │
└──────┬──────────────────┬──────────┘
│ │
┌────────────▼───────┐ ┌───────▼──────────────┐
│ LLM Expansion Svc │ │ Embedding Service │
│ - synonym/dialect │ │ (Arabic bi-encoder, │
│ - query rewrite │ │ e.g., GATE/AraBERT)│
│ - cache + timeout │ └───────┬──────────────┘
│ - fallback: raw q │ │
└────────────┬───────┘ │
▼ ▼
┌────────────────────────────────────────────────────────────┐
│ Elasticsearch │
│ BM25 (arabic analyzer) ✚ kNN dense_vector (HNSW) │
│ fused via RRF retriever (or weighted-sum) │
└──────────────────────────┬─────────────────────────────────┘
│ product_ids + score
▼
┌──────────────────────────────┐
│ MySQL │ ← source of truth
│ price, stock, seller, joins │ (never stale-critical)
└──────────────────────────────┘
▲
│ CDC / outbox sync (Debezium or dual-write)
┌─────────────┴────────────────┐
│ Indexer / Sync Worker │ → enriches docs,
│ │ embeds text,
│ │ upserts to ES
└───────────────────────────────┘
Naming clarity (defend this!)
| Term | Meaning in your thesis |
|---|---|
| Polyglot persistence | MySQL = transactional system of record; ES = derived read/search projection. Engineering decision. |
| Hybrid retrieval | Lexical (BM25) ⊕ Dense (kNN) fusion inside ES. IR-science decision. |
| LLM query expansion | Pre-retrieval query understanding step. Your main research object. |
2. Data Layer
2.1 MySQL (source of truth)
Standard normalized catalog schema:
products(id PK, sku, seller_id, category_id FK, brand_id FK,
price, currency, stock_qty, status, created_at, updated_at)
product_translations(product_id FK, locale ENUM('ar','en'),
title, description, attributes JSON)
categories(id, parent_id, name_ar, name_en)
brands(id, name_ar, name_en, aliases JSON) -- e.g. سامسونج/Samsung2.2 Sync to Elasticsearch
- Preferred: Debezium CDC on binlog → Kafka → indexer worker (true production pattern; nice thesis chapter).
- Acceptable fallback: outbox table + polling worker.
- The worker denormalizes into one search document per product:
{ "id": 123, "title_ar": "ثلاجة سامسونج نوفرو ٢٠ قدم", "description_ar": "...", "category_path": ["أجهزة منزلية", "ثلاجات"], "brand": "سامسونج", "attributes": {"capacity_liter": 580, "color": "فضي"}, "price": 24999, "stock": 12, "embedding": [0.11, -0.23, ...] }
3. Elasticsearch Index Design
3.1 Arabic analyzer chain (lexical side)
PUT products_ar
{
"settings": {
"analysis": {
"filter": {
"arabic_normalize": { "type": "arabic_normalization" },
"arabic_stem": { "type": "stemmer", "language": "arabic" },
"brand_synonyms": { "type": "synonym_graph",
"synonyms_path": "analysis/brand_synonyms.txt",
"lenient": true }
},
"analyzer": {
"arabic_search": {
"tokenizer": "standard",
"char_filter": ["tatweel_removal"],
"filter": ["lowercase", "arabic_normalize",
"brand_synonyms", "arabic_stem"]
}
}
}
},
"mappings": {
"properties": {
"title_ar": {
"type": "text",
"analyzer": "arabic_search",
"fields": {
"keyword": { "type": "keyword" },
"suggest": { "type": "search_as_you_type" }
}
},
"description_ar": { "type": "text", "analyzer": "arabic_search" },
"embedding": { "type": "dense_vector", "dims": 768,
"index": true, "similarity": "cosine" }
}
}
}What each filter solves from your problem table: | Problem | Filter | |---|---| | ثلاجة/ثلاجه، أرنب/ارنب | arabic_normalization (alef variants→ا, ta-marbuta→ه, alef-maqsura→ي) | | تشكيل / tatweel | standard tokenizer drops harakat; char_filter strips ـ | | والثلاجات morphology | stemmer(language:arabic) light stemmer | | سامسونج/Samsung | curated synonym_graph file |
Key insight to state explicitly: rule-based filters fix orthography, but cannot know that براد = ثلاجة. That lexical gap is exactly what your LLM layer adds — this sentence is the bridge between your two components and belongs in the intro of both the thesis and any presentation.
3.2 Hybrid query (BM25 + kNN via RRF)
GET products_ar/_search
{
"retriever": {
"rrf": {
"retrievers": [
{ "standard": {
"query": {
"bool": {
"should": [
{ "match": { "title_ar": { "query": "{{q}} {{expansions}}" } } },
{ "match": { "description_ar": { "query": "{{q}} {{expansions}}", "boost": 0.4 } } }
]
}
}
}},
{ "knn": {
"field": "embedding",
"query_vector": {{q_embedding}},
"k": 100, "num_candidates": 500
}}
],
"rank_constant": 60,
"rank_window_size": 100
}
},
"size": 20
}Then hydrate final IDs from MySQL for live price/stock before rendering.
4. LLM Expansion Service (the research core)
4.1 Three strategies (RQ2 arms)
- Synonym generation — prompt returns N alternative terms/phrases; OR-ed into the BM25 match (
براد,فريزر,رفريجيريتور). - Query rewrite — model rewrites whole query into canonical catalog language (
"تلاجة براد باردة كبيرة"→"ثلاجة كبيرة"). - Hypothetical document (HyDE-style) — model writes an imaginary product description answering the query; embed it and use as kNN probe (optionally also as expansion terms).
Prompt skeleton (strategy 1, Arabic):
أنت مساعد محرك بحث في متجر إلكتروني. المستخدم كتب الاستعلام التالي:
"{query}"
المطلوب: أعد حتى ٥ مرادفات أو تعبيرات بديلة قد يستخدمها البائع لوصف نفس المنتج،
مع مراعاة اللهجات العربية المختلفة والمسميات التجارية الشائعة.
أعد الإجابة بصيغة JSON فقط: {"expansions": [...]}
لا تضف أنواع منتجات مختلفة عن المنتج المقصود.
4.2 Guardrails (preempt examiner objections)
- Grounding: post-filter expansions against catalog vocabulary (drop terms with zero hits — CSQE-inspired).
- Never replace: original query always included; expansions are additive OR terms.
- Caching: Redis keyed by normalized query; head queries hit cache (H4).
- Timeout: 150–300 ms budget; on timeout/failure → fall back to non-expanded hybrid search.
- Category conditioning: feed top-3 predicted categories into prompt (Knowledge-aware QE idea).
4.3 Models to compare (grid)
Open/local: ALLaM-7B · Jais-13B · AceGPT-7B · Qwen2.5-7B (+ one small fine-tuned variant if time allows) Commercial: GPT-4o-mini-class tier · Claude Haiku class · Gemini Flash class Report per-model: effectiveness delta, latency P50/P95, $ cost / 1K queries, % hallucinated terms (post-filter drop rate).
5. Evaluation Methodology
5.1 Dataset construction (priority order)
- Seed:
prestoai/arabic-ecom-search-bench(HF) if quality checks pass. - Extend: machine-translate ESCI queries/products to Arabic → human spot-check ~20% sample (cite prior work using translated ESCI).
- Annotate new dialectal queries: follow WANDS guidelines (Exact/Partial/Irrelevant); target ≥300 queries × ≥50 judged products each; measure inter-annotator agreement (Cohen's κ ≥ 0.7 target).
5.2 System variants matrix
| # | System | Tests |
|---|---|---|
| S0 | MySQL LIKE/FULLTEXT (naive) | industry reality baseline |
| S1 | ES BM25 default analyzer | |
| S2 | ES BM25 + full Arabic analyzer | value of normalization (RQ1 part 1) |
| S3 | ES dense kNN only | |
| S4 | ES hybrid RRF (no LLM) | H2 / RQ3 |
| S5 | S2 + rule synonyms only | non-LLM expansion baseline |
| S6..Sn | S4 + each LLM × each strategy | H1/H3 / RQ1+2 |
Ablations: fusion method (RRF vs weighted sum), expansion count N∈{3,5,8}, grounding on/off, cache on/off.
5.3 Metrics & statistics
- Ranking: NDCG@10 (primary), MRR@10, Recall@100, Success@10.
- Efficiency: P50/P95 latency per stage, cost/query.
- Significance: paired bootstrap or randomization test over per-query NDCG (report p<0.05); report per-query-type breakdown (MSA vs dialect vs brand vs mixed-script).
- Error analysis chapter: sample of wins/failures per strategy, categorized (hallucination, wrong intent, dialect miss...).
6. Tech Stack (all free/open unless noted)
| Layer | Choice | Notes |
|---|---|---|
| DB | MySQL 8 | system of record |
| Search | Elasticsearch 8.x free tier (or OpenSearch 2.x) | kNN + RRF included |
| CDC | Debezium + Kafka (or simple worker) | |
| Embeddings | GATE / AraBERT-sentence / multilingual-e5 | pick via MTEB-Arabic scores |
| LLM serving | Ollama or vLLM locally; APIs for commercial | |
| Backend API | Python FastAPI | matches ML ecosystem |
| Eval harness | ranx / pytrec_eval + custom grid runner |
|
| Annotation | Label Studio (self-hosted) |
Minimum hardware for local experiments: 16 GB RAM Mac/Linux runs ES + 7B quantized LLM comfortably; 13B needs ~16 GB VRAM GPU or aggressive quantization.