Postgres پر Apache AGE کے ذریعے ویڈیو تعلقات کی کوئری کرنا
ریلیشنل ڈیٹا بیسز گہرے تعلقات (deep relationships) کو سنبھالنے میں مشکل محسوس کرتے ہیں۔
TrendVidStream میں، ہم آٹھ ریجنز میں اسٹریمنگ ٹائٹلز کا ایک کیٹلاگ مینیج کرتے ہیں۔ ہم نے شروع میں FTS5 کے ساتھ SQLite استعمال کیا تھا۔ یہ فل ٹیکسٹ سرچ اور سادہ ڈیپلائمنٹس کے لیے اچھا کام کرتا تھا۔
مسئلہ تب شروع ہوا جب صارفین نے پیچیدہ سوالات پوچھنا شروع کیے۔ وہ جاننا چاہتے تھے: "اس مخصوص ڈائریکٹر اور ان اداکاروں والی اس تھرلر فلم سے دو یا تین ہاپس (hops) دور اور کیا کچھ ہے؟"
SQL میں، اس کے لیے بہت سے self-joins کی ضرورت ہوتی ہے۔ ہر اضافی ہاپ کوئری کو برقرار رکھنا مشکل اور چلانے میں سست بنا دیتا ہے۔ join fan-out ایک ڈراؤنا خواب بن جاتا ہے۔
ہم نے PostgreSQL پر Apache AGE ایکسٹینشن کا استعمال کرتے ہوئے ایک گراف لیئر شامل کر کے اس کا حل نکالا۔
یہ تقسیم (split) کیوں کام کرتی ہے، اس کی وجوہات درج ذیل ہیں:
• آپ PostgreSQL کو برقرار رکھتے ہیں۔ آپ وہی کنکشنز، ٹرانزیکشنز اور بیک اپ ٹولز استعمال کرتے ہیں۔ آپ کو Neo4j کی طرح کسی الگ ڈیٹا بیس کی ضرورت نہیں پڑتی۔ • آپ گراف اور ریلیشنل ڈیٹا کو مکس کر سکتے ہیں۔ آپ Cypher کوئریز چلا سکتے ہیں اور نتائج کو اسٹینڈرڈ SQL ٹیبلز کے ساتھ جوڑ سکتے ہیں۔ • آپ متغیر گہرائی (variable depth) کو آسانی سے سنبھال سکتے ہیں۔ Cypher میں ایک سے تین ہاپس تک کے تعلقات تلاش کرنا ایک سادہ کمانڈ ہے۔ • آپ سادگی برقرار رکھتے ہیں۔ گراف آپ کے ڈیٹا کا ایک پروجیکشن (projection) ہے، نہ کہ حقیقت کا کوئی الگ ذریعہ (separate source of truth)۔
ہمارا ماڈل چار vertex labels استعمال کرتا ہے:
- Video
- Person
- Platform
- Region
ہم SIMILAR_TO، WORKED_ON، اور AVAILABLE_IN جیسے مخصوص edge types استعمال کرتے ہیں۔
ایک اہم سبق: اپنے انٹری پوائنٹس (entry points) کو ہمیشہ انڈیکس کریں۔ ہم Video vertices پر ext_id پراپرٹی کو انڈیکس کرتے ہیں۔ اس کے بغیر، ہر traversal ایک سست sequential scan کے ساتھ شروع ہوتا ہے۔
اس کا نتیجہ سفارشات (recommendations) کے لیے ایک صاف ستھری اور پڑھنے کے قابل کوئری ہے:
SELECT * FROM cypher('discovery', $$
MATCH (seed:Video {ext_id: 'vid_8842'})
MATCH (seed)-[:SIMILAR_TO|WORKED_ON*1..3]-(rec:Video)-[:AVAILABLE_IN]->(:Region {code: 'DE'})
WHERE rec.ext_id <> 'vid_8842'
RETURN DISTINCT rec.ext_id, rec.title, rec.year
LIMIT 24
$$) AS (ext_id agtype, title agtype, year agtype);
یہ کوئری تین ہاپس کے اندر متعلقہ ویڈیوز تلاش کرتی ہے جو جرمنی میں دستیاب ہیں۔ SQL میں، یہ جوائنز (joins) کا ایک بہت بڑا ڈھیر ہوتا۔ Cypher میں، یہ ایک سادہ پیٹرن ہے۔
ہم نے ٹیکسٹ سرچ کے لیے SQLite کو برقرار رکھا اور کنیکٹیویٹی کے لیے AGE کا استعمال کیا۔ ہر ٹول وہی کرتا ہے جس میں وہ بہترین ہے۔
