下载安装neo4j
步骤:
- 官方网址:https://neo4j.com
- 创建一个本地的 Graph
- 创建一个项目,neo4j 运行的服务器地址:http://localhost:7474/browser/
- testGraph.png
增删改查
查询 -> MATCH
MATCH (item) RETURN item // 查询显示所有节点和关系,item是变量
MATCH (item) RETURN item LIMIT 5 // 添加限制
MATCH (anyone:Person) RETURN anyone LIMIT 5 // 添加 label
MATCH (node1)--(node2) // 添加 relationship
RETURN node1, node2
LIMIT 3
// shift+enter 换行输入
MATCH (node1)-[rel]-(node2)
RETURN node1, rel, node2
// 指定关联方向
MATCH (node1)-[rel]->(node2), MATCH (node1)<-[rel]-(node2)
// 指定 label
MATCH (actor:Person)-[rel:ACTED_IN]->(movie:Movie)
RETURN actor, rel, movie
// 匹配多个 label
MATCH (actor:Person)-[rel:ACTED_IN | DIRECTED]->(movie:Movie)
// 多个匹配项, 返回有
MATCH (movie:Movie)
MATCH (director:Person)-[:DIRECTED]-(movie) // 等价于 MATCH (director:Person)-[:DIRECTED]->(movie:Movie)
RETURN movie.title // 使用node
// 使用OPTIONAL返回所有项,不匹配的置为NULL
MATCH (movie:Movie)
OPTIONAL MATCH (director:Person)-[:DIRECTED]->(movie)<-[:ACTED_IN]-[director]
使用条件查询
// 添加搜索条件, 不适用 where 和 使用 where
MATCH (p{name:"Tom Hanks"}) // 全局搜索
RETURN p
MATCH (p:Person{name: "Tom Hanks", born: 1956}) // 搜索标签为Person,且对应属性的节点
RETURN p
MATCH (p:Person{name: "Tom Hanks", born: 1956})
WHERE p.name = "Tom Hanks" AND p.born = 1956
RETURN p
// 筛选参与了某部电影,但是不是导演该电影的关系图
// WHERE 中只能使用已定义的变量
MATCH (person:Person)-->(movie:Movie)
WHERE movie.title = "Unforgiven" AND NOT (person)-[:DIRECTED]->(movie)
RETURN person, movie
WHERE 支持的比较运算符
- AND, OR
- IN [1997, 1998, 1999]
- =, <>, >, >=, <=, ...
- p.name >= 'T' AND < 'U' // 选择T开头的字符串
- 正则表达式匹配
- movie.title =~ "The.*" // The 开头的
- movie.title =~ "(?i)The .*" // 忽略大小写的 the
搜索结果处理
- ORDER BY XXX ASC/DESC // 排序
- SKIP 3 // 跳过前几个输出
- LIMIT 2 // 输出结果的前几个数
- AS // 设置结果列项别名
- DISTINCT XXX // 删除重复项
- 统计函数
- COUNT(XXX) // 计数
- SUM(XXX) // 求和
- AVG(XXX)
- MIN(XXX)
- MAX(XXX)
- 修改字符串
- toString(XXX) // 转化为字符串格式
- trim(XXX) // 删除空格
- REPLACE(str, old_sub_str, new_sub_str) // 替换字符串
- UPPER
- 数学计算方法
- abs()
- floor(X) // 向下取整
- ceil(X) // 向上取整
- round(x) // 四舍五入取整
- havesin() // 计算距离
- ...
练习
// 返回 A-B-C 关系
MATCH (p1:Person)-[:HAS_CONTACT]->(p2:Person)-[:HAS_CONTACT]->(p3:Person)
WHERE p1 <> p3
return p1, p2, p3
limit 2
增 -> CREATE
// 增加节点
CREATE () // 创建一个空节点,只有一个id属性;MATCH (node) WHERE id(node) = XXX RETURN node
CREATE (:label_name) // 创建一个节点,拥有一个label
CREATE (:label_name1:label_label2:...) // 创建一个节点,拥有多个label
CREATE ({sound:"Meow", eats: "mouse"}) // 创建一个节点,拥有多个属性
CREATE (cat:Cat:Animal{sound:"Meow", eats: "mouse"}) // 同时创建一个节点,拥有标签和属性
// 增加关联
CREATE (cat:Cat{name:"FF"})-[:GROOMS]->(cat) // 创建一个节点,和一个关联自己的关系
CREATE (cat:Cat{name:"FF"})-[:GROOMS{period:"Daily"}]->(cat) // 添加关联的属性
CREATE (:Buddy:Animal{name:"Joe"}), (:Buddy:Animal{name:"Sarah"})
CREATE (joe)-[:LIKES]->(sarah), (joe)<-[:LIKES]-(sarah) // 每次运行都会重复创建;
// 避免重复创建
MERGE (Buddy:Animal{name:"Cici"}) // 如果没有就创建,有就覆盖
MATCH (joe:Buddy:Animal{name:"Joe"}), (sarah:Buddy:Animal{name:"Sarah"})
MERGE (joe)-[:LIKES]->(sarah) // 覆盖插入关联
MERGE (joe)<-[:LIKES]-(sarah) // 覆盖插入关联
RETURN joe, sarah
举例
// 创建一个导演,电影;并关联他们,
CREATE (movie:Movie{title:"The Hateful Eight"}), (quentin:Persion{name:"Wuentin Tarantino"}), (quentin)-[:DIRECTED]->(movie)
RETURN quentin, movie
删 -> DELETE
// 删除所有关系和节点
MATCH (n) DETACH DELETE n
// 删除匹配条件的节点和节点关联
MATCH (n)
WHERE n.name = "XXX"
DETACH DELETE n
// 或者 MATCH (n:Lable(property:"XXX")) DETACH DELETE n
// 删除关系
MATCH (tom:Person{name: "Tom Hanks"}), (other)-[rel:HAS_CONTACT]->(tom)
DELETE rel
// 删除 有关联的节点和关系;无关联的node不会被删除
MATCH (node)-[rel]-()
DELETE node, rel
// 删除所有关系和节点
MATCH (node)
OPTIONAL MATCH (node)-[rel]-()
DELETE node, rel
改 -> SET
// 修改/添加属性
MATCH (tom:Person{name: "Tom Hanks"})
SET tom.sex = "male"
RETURN tom
// 添加标签
MATCH (tom:Person{name: "Tom Hanks"})
SET tom:Hansome
RETURN tom
// 删除标签
MATCH (tom:Person{name: "Tom Hanks"})
REMOVE tom:Hansome
RETURN tom
set预设变量
// 错误 Neo.ClientError.Statement.SyntaxError: Invalid use of aggregating function count(...) in this context (line 2, column 27 (offset: 89))
// "SET tom.num_of_contacts = COUNT(contact)"
// ^
MATCH (tom:Person{name:"Tom Hanks"})-[:HAS_CONTACT]->(contact)
SET tom.num_of_contacts = COUNT(contact)
RETURN tom
// 正确方式
MATCH (tom:Person{name:"Tom Hanks"})-[:HAS_CONTACT]->(contact)
WITH tom, COUNT(contact) AS num_of_contacts
SET tom.num_of_contacts = num_of_contacts
RETURN tom
设置 SET 创建和匹配动作
// "ON CREATE SET", 只有执行了创建动作,才执行的动作
MERGE (location:Location{name:"New York"})
ON CREATE SET location.created_at = timestamp(), location.created = "Tom"
RETURN location
// "ON MATCH SET"每次匹配了,要执行的动作
MERGE (location:Location{name:"New York"})
ON CREATE SET location.created_at = timestamp(), location.created = "Tom"
ON MATCH SET location.updated_at = timestamp()
RETURN location
修改 relationships
先创建一个新的;拷贝旧的;删除旧的关系
// 在之前的relationship添加两个属性
MATCH (tom:Person{name:"Tom Hanks"})-[orig_rel:HAS_CONTACT]->(bill:Person{name:"Bill Paxton"})
SET orig_rel.prop1 = 123, orig_rel.prop4 = 456
RETURN tom, bill
MATCH (tom:Person{name:"Tom Hanks"})-[orig_rel:HAS_CONTACT]->(bill:Person{name:"Bill Paxton"})
CREATE (tom)-[new_rel:CONTACETED]->(bill)
SET new_rel = orig_rel
DELETE orig_rel
RETURN tom, bill
练习
// 新加标签和属性
MATCH (actor:Person)-[role:ACTED_IN]->(:Movie)
WITH actor, SUM(role.earnings) AS total_earnings
WHERE total_earnings > 50000000
SET actor:Rich, actor.total_earnings = total_earnings
RETURN actor
// 删除标签和属性
MATCH (actor:Person)-[role:ACTED_IN]->(:Movie)
REMOVE actor:Rich, actor.total_earnings
RETURN actor
NULL 值
凡是返回不确定的值都为 NULLL
// 返回 NULL
MATCH (person:Person)
WITH (['Address1', 'Address2'] + person.address) AS partyDestionations
RETURN partyDestionations
LIMIT 11
// 返回 ["Address1", "Address2", null]
MATCH (person:Person)
WITH (['Address1', 'Address2'] + [person.address]) AS partyDestionations
RETURN partyDestionations
LIMIT 11
// 返回 ["Address1", "Address2"] ...
MATCH (person:Person)
WITH (['Address1', 'Address2'] + [person.address]) AS partyDestionations
RETURN [address IN partyDestionations WHERE address IS NOT NULL | address]
LIMIT 11
多层关系
MATCH path=((keanu:Person{name:"Keanu Reeves"})-[:HAS_CONTACT]->()-[:HAS_CONTACT]->())
RETURN path
LIMIT X // 避免回环
// 修改为两层关系
MATCH path=((keanu:Person{name:"Keanu Reeves"})-[:HAS_CONTACT*2]->())
RETURN path
LIMIT X
// 查看节点之间,可能关联条数
MATCH (keanu:Person{name: "Keanu Reeves"})
MATCH (tom:Person{name: "Tom Cruise"})
MATCH path = ((keanu)-[:HAS_CONTACT*..8]->(tom))
RETURN length(path)
LIMIT 1
// 查询最短路径
MATCH (keanu:Person{name: "Keanu Reeves"})
MATCH (tom:Person{name: "Tom Cruise"})
MATCH path = shortestPath((keanu)-[:HAS_CONTACT*..10]->(tom))
RETURN length(path)
// RETURN path, length(path) // 并显示path
// 查询所有最短路径
MATCH (keanu:Person{name: "Keanu Reeves"})
MATCH (tom:Person{name: "Tom Cruise"})
MATCH path = allshortestPaths((keanu)-[:HAS_CONTACT*..10]->(tom))
RETURN path, length(path)
Nth 表现形式
- *n: n层级别, 为0代表当前节点
- * 或者 *..: 代表所有可能的层,注意回环
- *..n: 0-n层
- *n..: 代表n层和n层以上
- *n..m: 代表n层到以及m层的层级节点
练习
// 找出两部电影之间关联的演员,最短关系
MATCH (matrixActor:Person)-[:ACTED_IN]->(matrix:Movie{title:"The Matrix"}),
(topGunActor:Person)-[:ACTED_IN]->(topGun:Movie{title:"Top Gun"}),
path = shortestPath((matrixActor)-[*..20]->(topGunActor))
RETURN matrix, topGun, path
LIMIT 3
// 优化条件,设置关系,开始结束节点不同,排序
MATCH (matrixActor:Person)-[:ACTED_IN]->(matrix:Movie{title:"The Matrix"}),
(topGunActor:Person)-[:ACTED_IN]->(topGun:Movie{title:"Top Gun"}),
path = shortestPath((matrixActor)-[:HAS_CONTACT*..20]->(topGunActor))
WHERE matrixActor <> topGunActor
RETURN matrix, topGun, path, length(path) AS pathLenght
ORDER BY pathLenght
LIMIT 2
网友评论