שאילתות על קשרי וידאו באמצעות Apache AGE ב-Postgres

מסדי נתונים רלציוניים מתקשים עם קשרים עמוקים.

ב-TrendVidStream, אנחנו מנהלים קטלוג של כותרים להזרמה (streaming) בשמונה אזורים. בתחילה השתמשנו ב-SQLite עם FTS5. זה עבד טוב עבור חיפוש טקסט מלא ופריסות פשוטות.

הבעיה החלה כאשר משתמשים התחילו לשאול שאלות מורכבות. הם רצו לדעת: "מה עוד נמצא במרחק של שניים או שלושה hops מהסרט המותח הזה, עם הבמאי הספציפי הזה והשחקנים האלה?"

ב-SQL, זה דורש הרבה self-joins. כל hop נוסף הופך את השאילתה לקשה יותר לתחזוקה ואיטית יותר להרצה. ה-join fan-out הופך לסיוט.

פתרנו זאת על ידי הוספת שכבת גרף באמצעות התוסף Apache AGE ב-PostgreSQL.

הנה הסיבות לכך שהחלוקה הזו עובדת:

• אתם שומרים על PostgreSQL. אתם משתמשים באותם חיבורים, טרנזקציות וכלי גיבוי. אין צורך במסד נתונים נפרד כמו Neo4j. • אתם מערבבים נתוני גרף ונתונים רלציוניים. אתם יכולים להריץ שאילתות Cypher ולחבר את התוצאות עם טבלאות SQL סטנדרטיות. • אתם מטפלים בעומק משתנה בקלות. מציאת קשרים במרחק של hop אחד עד שלושה היא פקודה פשוטה ב-Cypher. • אתם שומרים על פשטות. הגרף הוא הטלה (projection) של הנתונים שלכם, ולא מקור אמת (source of truth) נפרד.

המודל שלנו משתמש בארבע תוויות צמתים (vertex labels):

  • Video
  • Person
  • Platform
  • Region

אנחנו משתמשים בסוגי קשתות (edge types) ספציפיים כמו SIMILAR_TO, WORKED_ON, ו-AVAILABLE_IN.

לקח קריטי אחד: תמיד אינדקסו את נקודות הכניסה שלכם. אנחנו מאנדקסים את המאפיין ext_id בצמתי Video. ללא זה, כל traversal מתחיל בסריקה סדרתית (sequential scan) איטית.

התוצאה היא שאילתה נקייה וקריאה עבור המלצות:

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);

שאילתה זו מוצאת סרטונים קשורים בטווח של שלושה hops הזמינים בגרמניה. ב-SQL, זה היה ערימה עצומה של joins. ב-Cypher, זהו pattern פשוט.

שמרנו על SQLite לחיפוש טקסט והשתמשנו ב-AGE עבור קישוריות. כל כלי עושה את מה שהוא הכי טוב בו.

Source: https://dev.to/ahmet_gedik778845/querying-video-relationships-with-apache-age-graph-extension-on-postgres-3g54