【neo4j】 图数据库 2019-10-02

下载安装neo4j

步骤:

  1. 官方网址:https://neo4j.com
  2. 创建一个本地的 Graph
  3. 创建一个项目,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

参考文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容