ArangoDB - Kueri Contoh AQL

Pada bab ini, kita akan membahas beberapa Contoh Query AQL di file Actors and MoviesDatabase. Kueri ini didasarkan pada grafik.

Masalah

Diberikan koleksi aktor dan koleksi film, dan koleksi actIn edge (dengan properti tahun) untuk menghubungkan simpul seperti yang ditunjukkan di bawah ini -

[Actor] <- act in -> [Movie]

Bagaimana kita mendapatkan -

  • Semua aktor yang berakting di "movie1" ATAU "movie2"?
  • Semua aktor yang berakting di "movie1" DAN "movie2”?
  • Semua film umum antara "actor1" dan "actor2”?
  • Semua aktor yang berakting di 3 film atau lebih?
  • Semua film di mana tepatnya 6 aktor berakting?
  • Jumlah aktor menurut film?
  • Jumlah film menurut aktor?
  • Jumlah film yang diputar antara tahun 2005 dan 2010 menurut aktornya?

Larutan

Selama proses penyelesaian dan mendapatkan jawaban atas pertanyaan di atas, kami akan menggunakan Arangosh untuk membuat kumpulan data dan menjalankan kueri tentang itu. Semua kueri AQL adalah string dan dapat dengan mudah disalin ke driver favorit Anda, bukan Arangosh.

Mari kita mulai dengan membuat Set Data Pengujian di Arangosh. Pertama, unduh file ini -

# wget -O dataset.js
https://drive.google.com/file/d/0B4WLtBDZu_QWMWZYZ3pYMEdqajA/view?usp=sharing

Keluaran

...
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘dataset.js’
dataset.js [ <=> ] 115.14K --.-KB/s in 0.01s
2017-09-17 14:19:12 (11.1 MB/s) - ‘dataset.js’ saved [117907]

Anda dapat melihat pada output di atas bahwa kami telah mengunduh file JavaScript dataset.js.File ini berisi perintah Arangosh untuk membuat dataset di database. Alih-alih menyalin dan menempelkan perintah satu per satu, kami akan menggunakan--javascript.executeopsi di Arangosh untuk menjalankan beberapa perintah secara non-interaktif. Anggap saja perintah penyelamat hidup!

Sekarang jalankan perintah berikut di shell -

$ arangosh --javascript.execute dataset.js

Berikan kata sandi saat diminta seperti yang Anda lihat pada gambar di atas. Sekarang kita telah menyimpan datanya, jadi kita akan membuat query AQL untuk menjawab pertanyaan spesifik yang muncul di awal bab ini.

Pertanyaan pertama

Mari kita ambil pertanyaan pertama: All actors who acted in "movie1" OR "movie2". Misalkan, kami ingin menemukan nama semua aktor yang berakting di "TheMatrix" ATAU "TheDevilsAdvocate" -

Kami akan mulai dengan satu film pada satu waktu untuk mendapatkan nama-nama aktornya -

127.0.0.1:8529@_system> db._query("FOR x IN ANY 'movies/TheMatrix' actsIn
OPTIONS {bfs: true, uniqueVertices: 'global'} RETURN x._id").toArray();

Keluaran

Kami akan menerima output berikut -

[
   "actors/Hugo",
   "actors/Emil",
   "actors/Carrie",
   "actors/Keanu",
   "actors/Laurence"
]

Sekarang kita melanjutkan untuk membentuk UNION_DISTINCT dari dua query NEIGHBORS yang akan menjadi solusi -

127.0.0.1:8529@_system> db._query("FOR x IN UNION_DISTINCT ((FOR y IN ANY
'movies/TheMatrix' actsIn OPTIONS {bfs: true, uniqueVertices: 'global'} RETURN
y._id), (FOR y IN ANY 'movies/TheDevilsAdvocate' actsIn OPTIONS {bfs: true,
uniqueVertices: 'global'} RETURN y._id)) RETURN x").toArray();

Keluaran

[
   "actors/Charlize",
   "actors/Al",
   "actors/Laurence",
   "actors/Keanu",
   "actors/Carrie",
   "actors/Emil",
   "actors/Hugo"
]

Pertanyaan Kedua

Sekarang mari kita bahas pertanyaan kedua: All actors who acted in both "movie1" AND "movie2". Ini hampir sama dengan pertanyaan di atas. Tapi kali ini kami tidak tertarik pada UNION tetapi pada INTERSECTION -

127.0.0.1:8529@_system> db._query("FOR x IN INTERSECTION ((FOR y IN ANY
'movies/TheMatrix' actsIn OPTIONS {bfs: true, uniqueVertices: 'global'} RETURN
y._id), (FOR y IN ANY 'movies/TheDevilsAdvocate' actsIn OPTIONS {bfs: true,
uniqueVertices: 'global'} RETURN y._id)) RETURN x").toArray();

Keluaran

Kami akan menerima output berikut -

[
   "actors/Keanu"
]

Pertanyaan Ketiga

Sekarang, mari kita pertimbangkan pertanyaan ketiga: All common movies between "actor1" and "actor2". Ini sebenarnya identik dengan pertanyaan tentang aktor biasa di movie1 dan movie2. Kami hanya perlu mengubah simpul awal. Sebagai contoh, mari kita temukan semua film yang dibintangi oleh Hugo Weaving ("Hugo") dan Keanu Reeves -

127.0.0.1:8529@_system> db._query(
   "FOR x IN INTERSECTION (
      (
         FOR y IN ANY 'actors/Hugo' actsIn OPTIONS 
         {bfs: true, uniqueVertices: 'global'}
          RETURN y._id
      ),
      
      (
         FOR y IN ANY 'actors/Keanu' actsIn OPTIONS 
         {bfs: true, uniqueVertices:'global'} RETURN y._id
      )
   ) 
   RETURN x").toArray();

Keluaran

Kami akan menerima output berikut -

[
   "movies/TheMatrixReloaded",
   "movies/TheMatrixRevolutions",
   "movies/TheMatrix"
]

Pertanyaan Keempat

Sekarang mari kita bahas pertanyaan keempat. All actors who acted in 3 or more movies. Pertanyaan ini berbeda; kita tidak bisa menggunakan fungsi tetangga di sini. Sebagai gantinya kita akan menggunakan indeks tepi dan pernyataan KUMPULKAN dari AQL untuk pengelompokan. Ide dasarnya adalah untuk mengelompokkan semua sisi dengan merekastartVertex(yang dalam dataset ini selalu menjadi aktornya). Kemudian kami menghapus semua aktor dengan kurang dari 3 film dari hasil karena di sini kami telah memasukkan jumlah film yang dimainkan aktor -

127.0.0.1:8529@_system> db._query("FOR x IN actsIn COLLECT actor = x._from WITH
COUNT INTO counter FILTER counter >= 3 RETURN {actor: actor, movies:
counter}"). toArray()

Keluaran

[
   {
      "actor" : "actors/Carrie",
      "movies" : 3
   },
   
   {
      "actor" : "actors/CubaG",
      "movies" : 4
   },

   {
      "actor" : "actors/Hugo",
      "movies" : 3
   },

   {
      "actor" : "actors/Keanu",
      "movies" : 4
   },

   {
      "actor" : "actors/Laurence",
      "movies" : 3
   },

   {
      "actor" : "actors/MegR",
      "movies" : 5
   },

   {
      "actor" : "actors/TomC",
      "movies" : 3
   },
   
   {
      "actor" : "actors/TomH",
      "movies" : 3
   }
]

Untuk pertanyaan yang tersisa, kita akan membahas formasi query, dan hanya menyediakan query. Pembaca harus menjalankan kueri itu sendiri di terminal Arangosh.

Pertanyaan Kelima

Sekarang mari kita bahas pertanyaan kelima: All movies where exactly 6 actors acted in. Ide yang sama seperti di kueri sebelumnya, tetapi dengan filter kesetaraan. Namun, sekarang kami membutuhkan film dan bukan aktornya, jadi kami mengembalikan file_to attribute -

db._query("FOR x IN actsIn COLLECT movie = x._to WITH COUNT INTO counter FILTER
counter == 6 RETURN movie").toArray()

Jumlah aktor menurut film?

Kami ingat dalam dataset kami _to di tepi sesuai dengan film, jadi kami menghitung seberapa sering sama _tomuncul. Ini jumlah aktornya. Kueri hampir identik dengan yang sebelumnya tetapiwithout the FILTER after COLLECT -

db._query("FOR x IN actsIn COLLECT movie = x._to WITH COUNT INTO counter RETURN
{movie: movie, actors: counter}").toArray()

Pertanyaan Keenam

Sekarang, mari kita pertimbangkan pertanyaan keenam: The number of movies by an actor.

Cara kami menemukan solusi untuk kueri kami di atas akan membantu Anda menemukan solusi untuk kueri ini juga.

db._query("FOR x IN actsIn COLLECT actor = x._from WITH COUNT INTO counter
RETURN {actor: actor, movies: counter}").toArray()