neo4j:Cypher查询入门(三)

neo4j使用使用Cypher查询图形数据,Cypher是描述性的图形查询语言,语法简单,功能强大。

和SQL很相似,Cypher语言的关键字不区分大小写,但是,属性值,标签,关系类型和变量是区分大小写的。

1)变量

变量用于对搜索模式的部分进行命名,并在同一个查询中引用,在()中命名变量,变量名是区分大小写的,示例代码创建了两个标量n和b,通过return子句返回变量b。

match (n) --> (b)

return b

2) 访问属性

在Cypher查询中,通过点号来访问属性,格式是Variable.PropertyKey,通过id函数来访问实体的id格式是id(Variable).

match(n) -->(b)

where id(n)  = 5 and b.age = 18

return b;

1. 创建节点

节点模式的构成:(var: label1 :label2 {key1:value1,key2:value2}).

每个节点都有一个整数id,创建新节点时,neo4j自动为节点设置ID值,在整个数据库中,节点的id值是递增和唯一的。

create (n:Person {name :'Tom Hanks', born:1956})

return n;

create (n:Person{name:'robert zemeckis', born:1951}) return n;

create(n:Movie{title:'Forrest Gup', released:1951}) return n;

2. 查询节点

通过match子句查询数据库,match子句用于指定搜索的模式,where子句为match子句增加谓词,对模式进行约束。

1)查询整个图数据库

match(n) return n;

2) 查询born属性小于1955的节点

match(n) 

where n.born <1955

return n;

3) 查询具有指定label的节点

match(n:movie) return n;

4) 查询具有指定属性的节点

match(n{name:'Tpm Hanks'}) return n;

3. 创建关系

关系的构成: StartNode - [var:relationtype {key1:value1,key2:values2}] -> EndNode

创建关系时,必须指定关系类型

1) 创建没有任何属性的关系

match(a:person), (b:movie)

where a.name = 'Robert Zemeckis' and b.title = 'Forrest Gup'

create (a) - [r: DIRECTED] -> (b)

return r;

2) 创建关系,并设置关系的属性

match(a:person),(b:movie)

where a.name = 'Tom Hanks' and b.title = 'Forrest Gup'

create (a) -[r:acted_in{roles:['Forrest'] }] -> (b)

return r;

4. 查询关系

在Cypher中,关系分为3种:“--”表示有关系,忽略关系的类型和方向;符号“-->” 和 "<--" 表示有方向的关系。

1)查询整个数据图形

match(n) return n;

2)查询跟指定节点有关系的节点

# 返回跟movie标签有关系的所有节点

match(n) -- (m:movie)

return n;

3) 查询有向关系的节点

match(:person{name:'Tom Hanks'} -->(movie)

return movie;

4) 为关系命名,通过[r]为关系定义一个变量名,通过函数type获取关系的类型

match(:person{ name :'Tom Hanks'}) -[r] ->(movie)

return r, type(r);

5)查询特定的关系类型,通过[var:relationshiptype{key:value}] 指定关系的类型和属性

match(:person{name:'Tom Hanks'} ) - [r:acted_in{ roles:'Forrest'}] -> (movie)

return r ,type(r);

5. 更新图形

set子句,用于更新实体的属性和节点的标签;

remove子句,用于移除实体的属性和节点的标签。

1) 创建一个完整的path

由于path是由节点和关系构成,当路径中的关系或节点不存在时,neo4j会自动创建。

create p = (vic:worker:person{name:'vic' , title:'developer'}) - [: works_at] -> (neo) <- [:works_at] - (michael:worker:person{name:'michael', title:'manager'})

return p;

变量neo代表的节点没有属性,但是,有一个ID值,通过ID值为该节点设置属性和标签。

2)为节点增加属性

通过节点的ID获取节点,neo4j推荐通过where子句和ID函数来实现。

match(n)

where id(n) = 203

set n.name = 'neo'

return n;

3)为节点增加标签

match(n)

where id(n) = 203

set n:company 

return n;

4)为关系增加属性


match(n) -[r]-(m)

where id(n) =203 and id(m) = 8

set r.team = 'Azure'

return n;

6. merge子句

merge子句的作用有两个:

    - 当模式存在时,匹配该模式;

    - 当模式不存在时,创建新的模式,功能是match子句和create子句的组合。

在mrge子句之后,可以显式指定on create 和on match子句,用于修改绑定的节点和关系的属性。

通过merge子句,可以指定图形中必须存在一个节点,该节点必须具有特定的标签,属性等,如果不存在,那么merge子句将创建相应的节点。

1)通过merge子句匹配搜索模式

匹配模式:一个节点有person标签,并且具有name属性;如果数据库不存在该模式,那么,创建新的节点,如果存在该模式,那么,绑定该节点。

merge(michael:person{name:'michael douglas'})

return michael;

2)在merge子句中指定on create子句

如果需要创建节点,那么执行on create 子句,修改节点的属性。

merge(keanu:person{name:'keanu reeves'}) 

on create set keanu.created = timestamp()

return keanu.name,keanu.created;

3)在merge子句中指定on match子句

如果节点已经存在于数据库中,那么,执行on match子句修改节点的属性。

merge(per:person)

on match set per.found = True, per.lastaccessed = timestamp()

return per.name, per.found, per.lastaccessed;

4) 在merge子句中同时指定on create和on match子句

merge(keanu:person{name:'Keanu Reeves'})

on create set keanu.created = timestamp()

on match set keanu.lastseen = timestamp()

return keanu.name, keanu.created, keanu.lastseen;

5)merge子句用于match或create一个关系

match(charlie:person{name:'Charlie Sheen'}), (wallstreet:movie{title:'Wall Street'})

merge (charlie) -[r:acted_in] ->(wallstreet)

return charlie.name, type(r), wallstreet.title;

6) merge子句用于match或create多个关系

match(oliver:person{name:'Oliver Stone'}), (reiner:person{name:'Rob Reiner'})

merge(oliver)-[:directed]->(mov:movie) <- [:acted_in]-(reiner)

return mov;

7)merge子句用于子查询

match(per:person)

merge(city:City{name:per.bornIn})

return person.name, person.bornIn,city;

match(per:person)

merge(per)-[r:has_chauffeur]->(chauffeur:Chauffeur{name:per.chauffeurName})

return per.name, per.chauffeurName, chauffeur;

match(per:person)

merge(city:City{name:per.bornIn})

merge(person) -[r:born_in] ->(city)

return per.name, per.bornIn, city;

8. 跟实体相关的函数

1)通过id函数,返回节点或关系的ID

match(:person{name:'Oliver  Stone'}) - [r] ->(movie)

return id(r);

2)通过type函数,查询关系的类型

match(:person{name:'Oliver Stone'}) - [r] -> (movie)
return type(r);

3)通过labels函数,查询节点的标签

match(:person{name:'Oliver Stone'}) -[r] - >(movie)

return lables(movie);

4)通过keys函数,查看节点或关系的属性值

match(a)

where a.name = 'Alice'

return keys(a);

5)通过properties函数,查看节点或关系的属性

create (p:person{name:'Stefan', city:'Berlin'})

return properties(p);

9. 模式

模式,用于描述如何搜索数据,模式的格式是:使用()标识节点,使用[]标识关系。

1)节点模式

节点具有标签和属性,Cypher为了引用节点,需要给节点命名:

    - (n):该模式用于描述节点,节点的变量名是n;匿名节点是()

    - (n: label):节点具有特定的标签label,也可以指定多个标签

    - (n{name:"Vic"}):节点具有name属性,且name属性的值是“Vic”,也可以指定多个属性

    - (n:label{name:"Vic"}):节点具有特定的标签和name属性,并且name属性值是“Vic”

2)关系模式

在属性图中,节点之间存在关系,关系通过[]表示,节点之间的关系通过箭头()-[]->()表示,例如:

    - [r]:关系的变量名是r;匿名关系是[]

    - [r:type]:关系类型是type,且每一个关系必须有且仅有一个类型

    - [r:type{name:"Friend"}]:关系的类型是type,关系具有属性name,并且name属性值是Friend

3)关联节点模式

节点之间通过关系联系在一起,由于关系具有方向性,因此,-->表示存在有向的关系,--表示存在关联,不指定关系的方向,例如:

    - (a) -[r]->(b):该模式用于描述节点ab之间存在有向的关系r

    - (a) -->(b):该模式用于描述a和b之间存在有向关系

4)变长路径的模式

从一个节点,通过直接关系,连接到另外一个节点,这个过程叫遍历,经过的节点和关系的组合叫做路径,路径是节点和关系的有序组合:

    - (a)-->(b):是步长为1的路径,节点a和b之间有关系直接关联

    - (a)-->()-->(b):是步长为2的路径,从节点a,经过两个关系和一个节点,到达节点b

Cypher语言支持变长路径模式,变长路径的表示方式是:[*N..M],N和M表示路径长度的最小值和最大值。

    - (a)-[*2]->(b):从a节点到b节点经过的路径长度为2

    - (a)-[*3..5]->(b):从a到b经过的路径长度,最小值是3,最大值是5

    - (a)-[*..5]->(b):从a到b的路径长度最大值是5

    - (a)-[*3..]->(b):从a到b路径长度最小值是3

    - (a)-[*]-(b):不限制路径长度

5)路径变量

  路径可以指定给一个变量,该变量是路径变量,用于引用查询路径。

p = (a)-[*3..5]->(b)

6)示例


查询模式:查找跟Filipa有关系的人,路径程度为1或2

match(me) -[:KNOWS*1..2]-(remote_friend)

where me.name = 'Flilipa'

return remote_friend.name;

10. 查询子句

1)with子句

一个查询有很多查询子句,每一个查询子句按照特定的顺序执行,每一个子句是查询的一部分,with子句表示查询的一部分,在该部分输出结果之前,把输出传递到其他子句中去。

with子句保留otherperson,并新增聚合查询count(*),通过where子句过滤,返回查询结果

match(david{name:'David'}) -- (otherperson) -->()

with otherperson, count(*) as foaf

where foaf > 1

return otherperson.name;

2) foreach子句

foreach子句,用于更新列表中的数据,更新的格式:

match p = (begin) -[*]->(end)

where begin.name = 'A' and end.name = 'D'

foreach (n in nodes(p) | set n.marked = TRUE);

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

推荐阅读更多精彩内容