Neo4j 綜合練習作業
作業說明
這個作業涵蓋了 Neo4j 的多個重要知識點,包括節點和關系的創建、查詢、更新、刪除以及高級查詢功能。請使用 Cypher 語句完成以下所有題目。
數據準備
首先執行以下語句創建示例數據:
ACTED_IN: 表示出演關系
DIRECTED: 表示導演關系
PRODUCED: 制片關系
FRIENDS_WITH: 朋友關系
// 創建人物節點
CREATE
(keanu:Person {name: 'Keanu Reeves', born: 1964, nationality: 'Canadian'}),
(laurence:Person {name: 'Laurence Fishburne', born: 1961, nationality: 'American'}),
(carrie:Person {name: 'Carrie-Anne Moss', born: 1967, nationality: 'Canadian'}),
(lana:Person {name: 'Lana Wachowski', born: 1965, nationality: 'American'}),
(lilly:Person {name: 'Lilly Wachowski', born: 1967, nationality: 'American'}),
(joel:Person {name: 'Joel Silver', born: 1952, nationality: 'American'}),
(hugo:Person {name: 'Hugo Weaving', born: 1960, nationality: 'Australian'}),
(emil:Person {name: 'Emil Eifrem', born: 1978, nationality: 'Swedish'}),// 創建電影節點
(matrix:Movie {title: 'The Matrix', released: 1999, tagline: 'Welcome to the Real World'}),
(matrix2:Movie {title: 'The Matrix Reloaded', released: 2003, tagline: 'Free your mind'}),
(matrix3:Movie {title: 'The Matrix Revolutions', released: 2003, tagline: 'Everything that has a beginning has an end'}),
(devils:Movie {title: 'The Devils Advocate', released: 1997, tagline: 'Evil has its winning ways'}),
(few:Movie {title: 'A Few Good Men', released: 1992, tagline: 'In the heart of the nation\'s capital, in a courthouse of the U.S. government, one man will stop at nothing to keep his honor, and one will stop at nothing to find the truth.'}),// 創建關系
(keanu)-[:ACTED_IN {roles: ['Neo']}]->(matrix),
(keanu)-[:ACTED_IN {roles: ['Neo']}]->(matrix2),
(keanu)-[:ACTED_IN {roles: ['Neo']}]->(matrix3),
(keanu)-[:ACTED_IN {roles: ['Kevin Lomax']}]->(devils),
(laurence)-[:ACTED_IN {roles: ['Morpheus']}]->(matrix),
(laurence)-[:ACTED_IN {roles: ['Morpheus']}]->(matrix2),
(laurence)-[:ACTED_IN {roles: ['Morpheus']}]->(matrix3),
(carrie)-[:ACTED_IN {roles: ['Trinity']}]->(matrix),
(carrie)-[:ACTED_IN {roles: ['Trinity']}]->(matrix2),
(carrie)-[:ACTED_IN {roles: ['Trinity']}]->(matrix3),
(hugo)-[:ACTED_IN {roles: ['Agent Smith']}]->(matrix),
(hugo)-[:ACTED_IN {roles: ['Agent Smith']}]->(matrix2),
(hugo)-[:ACTED_IN {roles: ['Agent Smith']}]->(matrix3),
(emil)-[:ACTED_IN {roles: ['Emil']}]->(matrix),
(lana)-[:DIRECTED]->(matrix),
(lana)-[:DIRECTED]->(matrix2),
(lana)-[:DIRECTED]->(matrix3),
(lilly)-[:DIRECTED]->(matrix),
(lilly)-[:DIRECTED]->(matrix2),
(lilly)-[:DIRECTED]->(matrix3),
(joel)-[:PRODUCED]->(matrix),
(joel)-[:PRODUCED]->(matrix2),
(joel)-[:PRODUCED]->(matrix3),// 創建一些朋友關系
(keanu)-[:FRIENDS_WITH]->(emil),
(keanu)-[:FRIENDS_WITH]->(carrie),
(carrie)-[:FRIENDS_WITH]->(laurence),
(emil)-[:FRIENDS_WITH]->(joel);
作業題目
基礎查詢
- 查詢所有Person節點,只返回name屬性
- 查詢所有Movie節點,返回title和released屬性
- 查詢出演過"The Matrix"電影的所有演員的姓名
- 查詢Keanu Reeves出演過的所有電影的標題
條件查詢
- 查詢1990年到2000年之間發布的電影
- 查詢國籍不是"American"的演員
- 查詢出演過至少2部電影的演員
- 查詢既出演過電影又擔任過導演的人
關系查詢
- 查詢Keanu Reeves的朋友(直接朋友,不包括朋友的朋友)
- 查詢與Keanu Reeves有2跳關系的所有人(朋友的朋友)
- 查詢與"The Matrix"電影相關的所有人(包括演員、導演、制片人)
- 查詢共同出演過電影的演員對
聚合與排序
- 統計每部電影的演員數量,并按數量降序排列
- 查詢每個演員出演的電影數量,并按數量降序排列
- 查詢最年輕的5位演員
更新操作
- 為Keanu Reeves添加一個新的屬性"gender",值為"male"
- 將"The Matrix"電影的tagline更新為"The one that started it all"
- 刪除Emil Eifrem和Joel Silver之間的朋友關系
- 為電影"A Few Good Men"添加一個導演節點Rob Reiner(生于1947年,國籍American),并建立導演關系
路徑查詢
- 查找Keanu Reeves到Hugo Weaving的最短路徑(任何關系都可以)
高級查詢
- 使用OPTIONAL MATCH查詢所有電影及其導演(如果有的話)
- 使用UNION查詢所有加拿大籍的演員和美國籍的導演
- 使用CASE表達式為演員分類:出生在1960年前的為"Senior",1960-1970年的為"Middle-aged",1970年后的為"Young"
- 使用WITH和LIMIT查詢出演電影最多的前3位演員
索引與約束
- 為Person節點的name屬性創建唯一約束
- 為Movie節點的title屬性創建索引
刪除操作
- 刪除電影"A Few Good Men"及其所有關系
- 刪除所有沒有出演任何電影的人員
作業答案
// 1. 查詢所有Person節點,只返回name屬性
MATCH (p:Person) RETURN p.name;// 2. 查詢所有Movie節點,返回title和released屬性
MATCH (m:Movie) RETURN m.title, m.released;// 3. 查詢出演過"The Matrix"電影的所有演員的姓名
MATCH (p:Person)-[:ACTED_IN]->(m:Movie {title: 'The Matrix'}) RETURN p.name;// 4. 查詢Keanu Reeves出演過的所有電影的標題
MATCH (p:Person {name: 'Keanu Reeves'})-[:ACTED_IN]->(m:Movie) RETURN m.title;// 5. 查詢1990年到2000年之間發布的電影
MATCH (m:Movie) WHERE m.released >= 1990 AND m.released <= 2000 RETURN m;// 6. 查詢國籍不是"American"的演員
MATCH (p:Person) WHERE p.nationality <> 'American' RETURN p.name;// 7. 查詢出演過至少2部電影的演員
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH p, count(m) AS movieCount
WHERE movieCount >= 2
RETURN p.name, movieCount;// 8. 查詢既出演過電影又擔任過導演的人
MATCH (p:Person)-[:ACTED_IN]->(:Movie), (p)-[:DIRECTED]->(:Movie)
RETURN DISTINCT p.name;// 9. 查詢Keanu Reeves的朋友
MATCH (p:Person {name: 'Keanu Reeves'})-[:FRIENDS_WITH]->(friend)
RETURN friend.name;// 10. 查詢與Keanu Reeves有2跳關系的所有人
MATCH (p:Person {name: 'Keanu Reeves'})-[:FRIENDS_WITH*2]->(friendOfFriend)
RETURN DISTINCT friendOfFriend.name;// 11. 查詢與"The Matrix"電影相關的所有人
MATCH (p:Person)-[r]->(m:Movie {title: 'The Matrix'})
RETURN p.name, type(r) AS role;// 12. 查詢共同出演過電影的演員對
MATCH (p1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(p2:Person)
WHERE p1 <> p2
RETURN p1.name, p2.name, m.title;// 13. 統計每部電影的演員數量
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
RETURN m.title, count(p) AS actorCount
ORDER BY actorCount DESC;// 14. 查詢每個演員出演的電影數量
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN p.name, count(m) AS movieCount
ORDER BY movieCount DESC;// 15. 查詢最年輕的5位演員
MATCH (p:Person)
RETURN p.name, p.born
ORDER BY p.born DESC
LIMIT 5;// 16. 為Keanu Reeves添加gender屬性
MATCH (p:Person {name: 'Keanu Reeves'})
SET p.gender = 'male'
RETURN p;// 17. 更新"The Matrix"的tagline
MATCH (m:Movie {title: 'The Matrix'})
SET m.tagline = 'The one that started it all'
RETURN m;// 18. 刪除Emil Eifrem和Joel Silver之間的朋友關系
MATCH (e:Person {name: 'Emil Eifrem'})-[r:FRIENDS_WITH]->(j:Person {name: 'Joel Silver'})
DELETE r;// 19. 為"A Few Good Men"添加導演
CREATE (rob:Person {name: 'Rob Reiner', born: 1947, nationality: 'American'});
MATCH (m:Movie {title: 'A Few Good Men'}), (p:Person {name: 'Rob Reiner'})
CREATE (p)-[:DIRECTED]->(m);// 20. 查找Keanu Reeves到Hugo Weaving的最短路徑
MATCH path = shortestPath((k:Person {name: 'Keanu Reeves'})-[*]-(h:Person {name: 'Hugo Weaving'}))
RETURN path;// 21. 使用OPTIONAL MATCH查詢所有電影及其導演
MATCH (m:Movie)
OPTIONAL MATCH (d:Person)-[:DIRECTED]->(m)
RETURN m.title, d.name AS director;// 22. 使用UNION查詢所有加拿大籍的演員和美國籍的導演
MATCH (p:Person {nationality: 'Canadian'})-[:ACTED_IN]->(:Movie)
RETURN p.name AS name, 'Actor' AS role
UNION
MATCH (p:Person {nationality: 'American'})-[:DIRECTED]->(:Movie)
RETURN p.name AS name, 'Director' AS role;// 23. 使用CASE表達式為演員分類
MATCH (p:Person)
RETURN p.name,
CASE WHEN p.born < 1960 THEN 'Senior'WHEN p.born >= 1960 AND p.born < 1970 THEN 'Middle-aged'ELSE 'Young'
END AS ageGroup;// 24. 使用WITH和LIMIT查詢出演電影最多的前3位演員
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH p, count(m) AS movieCount
ORDER BY movieCount DESC
LIMIT 3
RETURN p.name, movieCount;// 25. 為Person節點的name屬性創建唯一約束
CREATE CONSTRAINT unique_person_name FOR (p:Person) REQUIRE p.name IS UNIQUE;// 26. 為Movie節點的title屬性創建索引
CREATE INDEX movie_title_index FOR (m:Movie) ON (m.title);// 27. 刪除電影"A Few Good Men"及其所有關系
MATCH (m:Movie {title: 'A Few Good Men'})
DETACH DELETE m;// 28. 刪除所有沒有出演任何電影的人員
MATCH (p:Person)
WHERE NOT (p)-[:ACTED_IN]->()
DELETE p;
這個作業涵蓋了 Neo4j 和 Cypher 的大部分核心功能,包括 CRUD 操作、各種查詢模式、路徑查找、聚合函數、索引和約束等。完成這個作業后,你應該對 Neo4j 的使用有了全面的了解。