[Ingest] Tune parser/validator for real Divar+Medjobs data
CI/CD / CI · dotnet build (push) Successful in 2m53s
CI/CD / Deploy · hamkadr (push) Failing after 2m39s

Analyzed live Divar (POST search) and Medjobs (ad_listing sitemaps) data — both are free Persian text. Tighten the medical-relevance gate (drop generic «استخدام»/«شیفت» that match retail/restaurant ads; add clinical terms: بهیار/اتاق عمل/بیهوشی/رادیولوژی/آزمایشگاه/دیالیز/فوریت/تریاژ/… ) so off-topic Divar jobs get flagged, not treated as medical. Add clinical role synonyms in the heuristic parser (بهیار/کمک‌پرستار/سالمند→پرستار, اتاق عمل→تکنسین اتاق عمل, فوریت→فوریت‌های پزشکی, آزمایشگاه→کارشناس آزمایشگاه, فوق‌تخصص→پزشک متخصص…). Result on live data: Medjobs now yields ~9/30 queue-ready healthcare listings; Divar correctly flags ~72/75 noise for manual review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-07 22:34:05 +03:30
parent 33c13ec524
commit 018c0f0286
2 changed files with 20 additions and 3 deletions
+13 -1
View File
@@ -51,7 +51,19 @@ public class HeuristicListingParser : IListingParser
{
if (text.Contains(Normalize(role))) { p.RoleName = role; break; }
}
if (p.RoleName is null && ContainsAny(text, "پزشک", "دکتر")) p.RoleName = "پزشک عمومی";
// Synonyms common on Divar/Medjobs → canonical seeded role names.
if (p.RoleName is null)
{
p.RoleName =
ContainsAny(text, "اتاق عمل", "اسکراب") ? "تکنسین اتاق عمل"
: ContainsAny(text, "فوریت", "اورژانس پیش بیمارستانی", "آمبولانس") ? "تکنسین فوریت‌های پزشکی"
: ContainsAny(text, "آزمایشگاه", "علوم آزمایشگاهی", "نمونه گیر") ? "کارشناس آزمایشگاه"
: ContainsAny(text, "بهیار", "کمک بهیار", "کمک پرستار", "بیماربر", "مراقب", "سالمند", "همراه بیمار", "تزریقات", "پانسمان") ? "پرستار"
: ContainsAny(text, "ماما", "مامایی") ? "ماما"
: ContainsAny(text, "فوق تخصص", "متخصص") ? "پزشک متخصص"
: ContainsAny(text, "پزشک", "دکتر", "طبیب") ? "پزشک عمومی"
: null;
}
p.Notes.Add(p.RoleName is null ? "نقش: تشخیص داده نشد" : $"نقش: {p.RoleName}");
// --- Shift type ---
@@ -20,10 +20,15 @@ public class ListingValidator
"بک لینک", "تبلیغات", "قرعه کشی", "جایزه", "کازینو", "شرط بندی", "بیت کوین"
};
// Clinical/health markers ONLY. Deliberately excludes generic words like «استخدام» and «شیفت»
// (they match retail/restaurant ads on Divar). A post must contain a real care-domain term.
private static readonly string[] MedicalMarkers =
{
"شیفت", "درمانگاه", "بیمارستان", "کلینیک", "پزشک", "پرستار", "ماما", "تکنسین",
"اورژانس", "استخدام", "کادر درمان", "مطب", "آنکال", "کشیک"
"درمانگاه", "بیمارستان", "کلینیک", "مطب", "اورژانس", "کادر درمان", "پلی کلینیک",
"پزشک", "دکتر", "پرستار", "بهیار", "کمک بهیار", "کمک پرستار", "بیماربر",
"ماما", "مامایی", "تکنسین", "اتاق عمل", "بیهوشی", "رادیولوژی", "سونوگرافی",
"آزمایشگاه", "تزریقات", "پانسمان", "فیزیوتراپ", "دندان", "داروخانه", "داروساز",
"دیالیز", "فوریت", "آی سی یو", "سی سی یو", "آنکال", "کشیک", "تریاژ", "نوزادان", "سالمند"
};
public ValidationResult Validate(string rawText, ParsedListing parsed)