Zapytania o relacje wideo za pomocą Apache AGE na Postgresie

Relacyjne bazy danych mają trudności z głębokimi relacjami.

W TrendVidStream zarządzamy katalogiem tytułów streamingowych w ośmiu regionach. Pierwotnie używaliśmy SQLite z FTS5. Sprawdzało się to dobrze w przypadku wyszukiwania pełnotekstowego i prostych wdrożeń.

Problem pojawił się, gdy użytkownicy zaczęli zadawać złożone pytania. Chcieli wiedzieć: „Co jeszcze znajduje się dwa lub trzy kroki od tego thrillera z tym konkretnym reżyserem i tymi aktorami?”.

W SQL wymaga to wielu złączeń typu self-join. Każdy dodatkowy krok sprawia, że zapytanie jest trudniejsze w utrzymaniu i wolniejsze w działaniu. Rozrost złączeń (join fan-out) staje się koszmarem.

Rozwiązaliśmy to, dodając warstwę grafową za pomocą rozszerzenia Apache AGE na PostgreSQL.

Oto dlaczego takie podejście działa:

• Zachowujesz PostgreSQL. Korzystasz z tych samych połączeń, transakcji i narzędzi do kopii zapasowych. Nie potrzebujesz oddzielnej bazy danych, takiej jak Neo4j. • Łączysz dane grafowe i relacyjne. Możesz uruchamiać zapytania Cypher i łączyć wyniki ze standardowymi tabelami SQL. • Łatwo obsługujesz zmienną głębokość. Znalezienie połączeń w odległości od jednego do trzech kroków to w Cypher prosta komenda. • Zachowujesz prostotę. Graf jest projekcją Twoich danych, a nie oddzielnym źródłem prawdy (source of truth).

Nasz model wykorzystuje cztery etykiety wierzchołków:

  • Video
  • Person
  • Platform
  • Region

Używamy specyficznych typów krawędzi, takich jak SIMILAR_TO, WORKED_ON i AVAILABLE_IN.

Jedna krytyczna lekcja: zawsze indeksuj punkty wejścia. Indeksujemy właściwość ext_id w wierzchołkach Video. Bez tego każde przechodzenie (traversal) zaczyna się od powolnego skanowania sekwencyjnego.

Wynikiem jest czyste, czytelne zapytanie do rekomendacji:

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

To zapytanie znajduje powiązane filmy w odległości do trzech kroków, które są dostępne w Niemczech. W SQL byłaby to ogromna sterta złączeń. W Cypher to prosty wzorzec.

Zachowaliśmy SQLite do wyszukiwania tekstowego i użyliśmy AGE do obsługi połączeń. Każde narzędzie robi to, w czym jest najlepsze.

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