Graph Database แบบกราวน์ๆ

หลังจากบทความที่แล้ว ที่เราได้รู้จักส่วนประกอบต่างๆ ของ Graph Database Browser กันแล้ว บทความนี้เราก็จะมาเริ่มใช้งาน Graph Database กันเลยดีกว่าครับ

สำหรับ Query Command ที่ใช้ใน Graph Database(neo4j) เราจะเรียกว่า Cypher

เริ่มต้นเราจะสร้าง Database ที่ชื่อว่า PlayGround1 กัน โดยใช้คำสั่งข้างล่างแล้วกด Enter

$> Create Database PlayGround1 

เมื่อเราเปิดหน้าต่าง Database Information ขึ้นมา ในส่วนของ Use Database จะมีชื่อ Database ของเราเพิ่มเข้ามาแล้ว

หรือเราลองใช้คำสั่งนี้ เพื่อแสดงรายการ Database ก็ได้

$> :dbs

และให้ใช้คำสั่งนี้ เพื่อเลือก Database PlayGround1 มาใช้งาน

$> :use playground1

จากนั้นเราจะมาลองเพิ่มข้อมูลเข้าไปใน Database ของเรากันดีกว่าครับ โดยให้เราลองใช้คำสั่งนี้

$> CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})

จากนั้นลองทำการ Query ข้อมูลขึ้นมาดู โดยใช้คำสั่ง

$> Match (movie:Movie) Return movie

จะเห็นได้ว่าตอนนี้เราได้ Node ของข้อมูลขึ้นมาแล้ว 1 ตัว ถ้าเราเปิดในส่วนของ Database Information ขึ้นมาก็จะเจอกับ Node Labels, จำนวนข้อมูลทั้งหมด และ Properties Keys ต่างๆ ดังภาพ

สำหรับการ select ข้อมูลใน Graph Database เราจะใช้คำว่า Match แทน Select ใน SQL ครับ ลองมาดูเปรียบเทียบคำสั่งกันครับ

SQL Command

$> Select * from Movie

Graph Database

$> Match (movie:Movie) Return movie

จากนั้นให้เราลองเพิ่มข้อมูลของ Movie เข้าไปเพิ่ม โดยใช้คำสั่งเดิม (ใส่ข้อมูลซ้ำ) แล้วลองดูผลลัพธ์ของ Graph

ตอนนี้ตัว Graph เองจะแสดง Node ขึ้นมาด้วยกัน 2 Nodes แล้ว

หลังจากนั้นให้ใช้คำสั่งนี้เพื่อเคลียร์ข้อมูลออกทั้งหมด (Node, Relation)

$> Match (n) Detach Delete n

เมื่อเคลียร์ข้อมูลแล้ว ต่อไปเราลองมาสร้างข้อมูล 2 ชุดที่มีความสัมพันธ์กัน และมาดูกันว่า Graph จะออกมาเป็นอย่างไรกัน

เริ่มต้นเราจะใช้คำสั่ง Create ข้อมูล Movie จากตัวอย่างก่อนหน้านี้มาใช้งานกัน และจะเพิ่มข้อมูลของ Person เข้าไป

1> CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
2> CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})

จากนั้นมาดูผลลัพธ์ โดยใช้คำสั่ง

$> Match (n) return n

จากนั้นเรามาลองเพิ่มความสัมพันธ์ให้กับข้อมูลทั้ง 2 กัน โดย Keanu Reeves นั้นจะเป็นนักแสดงใน Movie เรื่อง The Matrix เราก็จะเขียนคำสั่ง

1> Match(person:Person{name:'Keanu Reeves'}),(movie:Movie{title:'The Matrix'})
2> Create(person)-[:ACTED_IN {roles:['Neo']}]->(movie)

จากนั้นเราจะลองมา Query ข้อมูลขึ้นมาดูกัน

$> Match (n) Return n

มาดูกันว่าคำสั่งที่ใช้ในการทำ Relation มีอะไรบ้างกันดีกว่าครับ

$> Match(person:Person{name:'Keanu Reeves'}),(movie:Movie{title:'The Matrix'})
  • สำหรับคำสั่ง (person:Person{name:’Keanu Reeves’}) นั้น เราจะทำการค้นหาข้อมูลจาก Person โดยมีเงื่อนไขว่าจะดึง Person ที่มีชื่อว่า ‘Keanu Reeves’ ขึ้นมา แล้วเก็บเอาไว้ในตัวแปร person
  • คำสั่งตรงนี้ (movie:Movie{title:’The Matrix’}) จะเหมือนกับข้างบน เพียงแต่เราจะเปลี่ยนไปเอาข้อมูลจาก Movie ที่มี Title ว่า ‘The Matrix’ มาเก็บเอาไว้ในตัวแปร movie
$> Create(person)-[:ACTED_IN {roles:['Neo']}]->(movie)

สำหรับคำสั่งนี้ จะเป็นการผูก Relation ของ person กับ movie โดยเราจะกำหนดชื่อว่า ‘ACTED_IN’ โดยจะมีการกำหนด property ชื่อว่า ‘Role’ และกำหนดค่าเอาไว้เป็น ‘Neo’

แล้วทีนี้ถ้าเราต้องการจะเพิ่มข้อมูลลงไปพร้อมกับความสัมพันธ์เลยละ ต้องทำยังไง เรามาลองทำกันเลยดีกว่าครับ

ก่อนอื่นให้ลบข้อมูลออกไปก่อนโดยใช้คำสั่งสำหรับการลบข้อมูลก่อนหน้านี้ครับ จากนั้นก็ให้ใช้คำสั่ง

$> Create (person:Person {name:'Keanu Reeves', born:1964})-[:ACTED_IN {roles:['Neo']}]->(movie:Movie{title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})

มาลองเรียกดูข้อมูลที่เพิ่มเข้าไปกัน

ขั้นตอนต่อไป เราจะทำการเพิ่มข้อมูลโดยใช้ข้อมูลตัวอย่างของ neo4j กัน เพื่อใช้สำหรับการทดลองค้นหาข้อมูลด้วยเงื่อนไขกัน โดยคำสั่งจะมีดังนี้

หลังจากเราเพิ่มข้อมูลเข้าไปแล้ว Database information ของเราก็จะมีรายละเอียดดังนี้

ทดลองค้นหาข้อมูลของ Movie ที่ชื่อว่า ‘Top Gun’ เราก็จะใช้คำสั่ง

$> Match (movie:Movie {title: 'Top Gun'}) Return movie

จากนั้นทดลอง Query ข้อมูลจากทั้ง Movie และ Person

1> Match(person:Person{name:'Keanu Reeves'}),(movie:Movie{title:'Top Gun'})
2> Return person,movie

ทีนี้เราลองมาดูว่าใครเป็นนักแสดงใน Movie เรื่อง The Matrix กันบ้างดีกว่า ด้วยคำสั่ง

1> Match(person:Person)-[d:ACTED_IN]->(movie:Movie {title:'The Matrix)
2> Return person,movie

มาลองเรียกข้อมูลขึ้นมาแสดงแบบกำหนดจำนวนกันดีกว่า โดยเราจะเพิ่ม limit เข้าไป

1> Match(person:Person)-[d:ACTED_IN]->(movie:Movie{title:'The Matrix'})
2> Return person,movie
3> Limit 2

ต่อไปเรามาลองเรียกดูปีเกิดของ Person กันด้วยคำสั่ง

$> Match(person:Person) Return person.name, person.born limit 10

ถ้าเกิดว่าเราอยากรู้ว่ามีใครเป็น Director ของ Movie เรื่องอะไรบ้าง เราก็สามารถใช้ Query แบบ Sub-Query ได้ เช่นกัน

1> Match(movie:Movie)
2> Match(director:Person)-[:DIRECTED]->(movie)
3> Return movie.title, director.name

แล้วถ้าเกิดว่าอยากจะรู้ว่า Director คนไหนที่รวมแสดงด้วยละ เราสามารถเพิ่ม
Sub-Query เข้าไปได้อีก

1> Match(movie:Movie)
2> Match(director:Person)-[:DIRECTED]->(movie)
3> Match(director)-[:ACTED_IN]->(movie)
4> Return movie.title, director.name

ทีนี้เรามาลองใช้ Optional เข้ามาช่วยเขียน Query กันดู

1> Match(movie:Movie)
2> Optional Match(director:Person)-[:DIRECTED]->(movie)<-[:ACTED_IN]-(director)
3> Return movie.title, director.name

จากคำสั่งข้างต้นทั้ง 2 คำสั่งนั้น จะได้ผลลัพธ์ที่ต่างกัน แต่ใช้เงื่อนไขเดียวกัน คือต้องการหาว่า Movie เรื่องไหนมี Director ร่วมแสดงด้วย เพียงแต่คำสั่งที่ใช้ Optional นั้นจะเป็นการ Query ข้อมูลของ Movie ทั้งหมดก่อน แล้วค่อยไปทำเงื่อนไขที่อยู่ในส่วนของ Optional นั่นเอง

สำหรับบทความในส่วนของการใช้งาน Graph Database Cypher เบื้องต้นแบบ
กราวน์ๆ ก็ขอจบเพียงเท่านี้ก่อนครับ หวังว่าพอจะมีประโยคสำหรับผู้ที่สนใจ Graph Database นะครับ หากผิดพลาดประการใดต้องขออภัยมา ณ ที่นี้ด้วยครับ

--

--