Di DailyWatch, panel "video terkait" kami bermula dari kueri SQLite yang sederhana. Kueri tersebut menggabungkan tiga tabel, menghitung tag yang tumpang tindih, dan mengembalikan daftar peringkat. Untuk katalog kecil, itu sudah cukup. Video memasak dengan tag "italian" dan "pasta" akan memunculkan video lain dengan tag yang sama, dan pengguna pun mengekliknya. Hasilnya terlihat relevan karena metadatanya bersih dan pustakanya masih dangkal.
Kemudian katalog berkembang, dan ekspektasi audiens pun berubah. Orang-orang tidak sekadar menginginkan lebih banyak video dengan tag yang identik. Mereka menginginkan klip yang ditonton oleh empat puluh persen penonton segera setelah video yang sedang berjalan. Mereka menginginkan saluran niche yang terus muncul dalam sesi menonton larut malam yang sama, meskipun deskripsinya tidak menyebutkan apa pun tentang video awal dan tag-nya sangat minim. Ini adalah pola perilaku, bukan sekadar kecocokan metadata. SQLite tidak dapat mengekspresikannya tanpa berubah menjadi sarang self-join dan recursive common table expressions yang tidak dapat dipelihara. Setiap sinyal baru yang kami coba modelkan, baik itu co-viewership maupun kedekatan sesi, menambah latensi dan beban kognitif. Kami menghadapi masalah graf yang dipaksakan ke dalam struktur relasional.
Saya memindahkan lapisan rekomendasi ke Apache AGE.
Apache AGE adalah ekstensi PostgreSQL yang menambahkan kueri graf openCypher ke basis data yang sudah Anda jalankan. Ini bukan server terpisah. Ini bukan sidecar. Ia berjalan di dalam Postgres, yang berarti kami dapat membangun jaringan co-view tanpa harus membangun klaster Neo4j khusus atau mempelajari panduan operasional yang sepenuhnya baru. Bagi tim kecil tanpa insinyur keandalan basis data, perbedaan itu sangatlah penting.
Mengapa Ekstensi Lebih Baik daripada Basis Data Baru
Menambahkan basis data graf ke tumpukan teknologi (stack) Anda terasa mudah di papan tulis, tetapi mahal di produksi. Anda memerlukan dasbor pemantauan baru, prosedur pencadangan baru, pool koneksi baru, dan logika failover baru. AGE menghindari semua itu karena ia hidup di dalam instansi Postgres Anda yang sudah ada.
Ada empat alasan praktis mengapa ini berhasil bagi kami.
- Tidak ada infrastruktur baru. Karena AGE adalah sebuah ekstensi, jadwal
pg_dumpAnda saat ini, replika yang ada, dan pemeriksaan kesehatan Postgres standar Anda semuanya tetap berfungsi. Anda tidak perlu meyakinkan tim operasional untuk mengurus penyimpanan data lainnya. - Beban kerja campuran dalam satu kueri. AGE memungkinkan Anda menulis Cypher di dalam SQL. Anda dapat menjalankan penelusuran graf untuk menemukan video kandidat, lalu menggabungkan set hasil tersebut dengan tabel relasional
usersAnda untuk menerapkan pembatasan konten regional, atau dengan tabel relasionalsponsorshipsuntuk menurunkan prioritas saluran tertentu. Satu round-trip. Dua bahasa kueri yang bekerja sama. - Portabilitas. Cypher adalah bahasa kueri graf yang terbuka dan terdokumentasi dengan baik. Jika DailyWatch tumbuh melampaui AGE dan perlu bermigrasi ke Neo4j atau Memgraph di kemudian hari, logika kuerinya dapat dipindahkan dengan penulisan ulang minimal. Anda tidak terkunci pada dialek proprietari.
- Kompatibilitas. Karena datanya pada akhirnya berada di PostgreSQL, alat bantu PHP atau Python Anda yang sudah ada tidak perlu berubah. Anda terhubung dengan driver yang sama, menangani string koneksi yang sama, dan mengambil baris dengan cara yang sama. Logika graf berada di lapisan kueri, bukan di lapisan aplikasi.
Memodelkan Co-Viewership
Implementasinya sangat lugas. Kami mendefinisikan node untuk entitas yang kami perlukan: Video dan Channel. Kami kemudian mendefinisikan edge untuk hubungan di antara keduanya. Sebuah edge PUBLISHED menghubungkan Channel ke Video. Sebuah edge CO_VIEWED menghubungkan satu Video ke Video lainnya, dengan membawa properti weight yang merepresentasikan seberapa sering kedua video tersebut muncul dalam sesi menonton yang sama.
Model ini menangkap sesuatu yang tidak bisa dilakukan oleh SQL berbasis tag: struktur implisit
