长沙网站建设王道下拉棒,电子商务网站建设的实训报告,做网站的软件m开头,软件工程师资格考试前言
neo4j的图查询语言叫Cypher。Cypher的独特之处在于它提供了一种匹配模式和关系的可视化方式。 (nodes)-[:ARE_CONNECTED_TO]-(otherNodes)使用圆角括号表示节点(nodes)#xff0c; -[:ARROWS]-表示关系。
语法
解析
Cypher解析器接受任意输入字符串。
unico…前言
neo4j的图查询语言叫Cypher。Cypher的独特之处在于它提供了一种匹配模式和关系的可视化方式。 (nodes)-[:ARE_CONNECTED_TO]-(otherNodes)使用圆角括号表示节点(nodes) -[:ARROWS]-表示关系。
语法
解析
Cypher解析器接受任意输入字符串。
unicode通常可以使用转义 \uxxx。
支持的空白符
描述Unicode 字符列表Unicode General Category Zp\u2029Unicode General Category Zs\u0020 (space), \u1680, \u2000-200A, \u202F, \u205F, \u3000Unicode General Category class Zl\u2028Horizontal Tabulation\t, \u0009Line Feed\n, \u000AVertical Tabulation\u000BForm Feed\f, \u000CCarriage Return\r, \u000DFile Separator\u001CGroup Separator\u001DRecord Separator\u001EUnit Separator\u001F
表达式
字面量
数值13, -40000, 3.14,6.022E23Inf, Infinity, NaN十六进制 0x13af, 0xFC3A9, -0x66eff。 以0x开头八进制0o1372, -0o5671 。以0o开头。字符串Hello , World 。单引号或者双引号booleantrue, false
通用表达式
变量n, x, rel, myFancyVariable属性 n.prop, x.prop, rel.thisProperty, myFancyVariable.动态属性 n[prop], rel[n.city n.zip], map[coll[0]].参数$param, $0List[a, b], [1, 2, 3], [a, 2, n.property, $param], []函数调用length(p), nodes(p)聚合函数avg(x.prop), count(*)path-pattern (a)-[r]-(b), (a)-[r]-(b), (a)--(b), (a)--()--(b)操作符 1 2, 3 4断言表达式a.prop Hello, length(p) 10, a.name IS NOT NULL标签和关系类型表达式(n:A|B), ()-[r:R1|R2]→().子查询EXISTS { MATCH (n)-[r]→(p) WHERE p.name Sven }正则表达式a.name ~ Tim.*字符串匹配a.surname STARTS WITH Sven, a.surname ENDS WITH son or a.surname CONTAINS sonCASE
CASE
通用条件表达式可以使用CASE结构表示。Cypher中存在CASE的两种变体:
简单形式(允许将一个表达式与多个值进行比较)通用形式(允许表示多个条件语句)。 如果您想在后续子句或语句中使用CASE表达式的结果CASE只能作为RETURN或WITH的一部分使用。 简单形式
CASE testWHEN value THEN result[WHEN ...][ELSE default]
ENDMATCH (n)
RETURN
CASE n.eyesWHEN blue THEN 1WHEN brown THEN 2ELSE 3
END AS result通用形式
谓词将按顺序求值直到找到一个真值并使用结果值。如果没有找到匹配项则返回ELSE子句中的表达式。但是如果没有ELSE情况并且没有找到匹配则返回null。
MATCH (n)
RETURN
CASEWHEN n.eyes blue THEN 1WHEN n.age 40 THEN 2ELSE 3
END AS result后续语句使用CASE表达式结果
您可以使用CASE的结果来设置节点或关系的属性。例如你可以为表达式选择的节点设置属性而不是直接指定节点:
MATCH (n)
WITH n, // 使用WITH 来处理结果
CASE n.eyesWHEN blue THEN 1WHEN brown THEN 2ELSE 3
END AS colourCode
SET n.colourCode colourCode处理null
MATCH (n)
RETURN n.name,
CASE n.ageWHEN null THEN -1ELSE n.age - 10
END AS age_10_years_ago子查询
子查询表达式可以出现在表达式有效的任何地方。子查询有一个范围由开始和结束大括号{和}表示。在外部作用域中定义的任何变量都可以在子查询自己的作用域中引用。在子查询内部引入的变量不是外部作用域的一部分因此不能在外部访问。
EXISTS子查询
EXISTS子查询可用于查明指定模式在数据中是否至少存在一次。它的用途与路径模式相同但功能更强大因为它允许在内部使用MATCH和WHERE子句。此外与路径模式不同它可以出现在任何表达式位置。如果子查询的求值至少为一行则整个表达式将变为真。这也意味着系统只需要评估是否至少有一行并且可以跳过其余的工作。
任何非写查询都是允许的。EXISTS子查询与常规查询的不同之处在于最终的RETURN子句可以省略因为在子查询中定义的任何变量在表达式之外都不可用即使使用了最终的RETURN子句。
值得注意的是如果EXISTS只包含一个模式和一个可选的where子句则可以在子查询中省略MATCH关键字。
简单形式
MATCH (person:Person)
WHERE EXISTS { //对Person进行关系判断(person)-[:HAS_DOG]-(:Dog)
}
RETURN person.name AS nameWhere子查询
MATCH (person:Person)
WHERE EXISTS {MATCH (person)-[:HAS_DOG]-(dog:Dog) //有matchwhere 更细的判断WHERE person.name dog.name
}
RETURN person.name AS name嵌套Exists
MATCH (person:Person)
WHERE EXISTS {MATCH (person)-[:HAS_DOG]-(dog:Dog)WHERE EXISTS {MATCH (dog)-[:HAS_TOY]-(toy:Toy)WHERE toy.name Banana}
}
RETURN person.name AS name作为结果
MATCH (person:Person)
RETURN person.name AS name, EXISTS {MATCH (person)-[:HAS_DOG]-(:Dog)
} AS hasDog //作为一个boolean值结果UNION 结合
Exists可以与UNION子句一起使用而RETURN子句不是必需的。值得注意的是如果一个分支有RETURN子句那么所有分支都需要RETURN子句。下面的示例演示了如果UNION分支中的一个至少返回一行那么整个EXISTS表达式将求值为true。
MATCH (person:Person)
RETURNperson.name AS name,EXISTS { //至少有1个 Pet。MATCH (person)-[:HAS_DOG]-(:Dog)UNION //UNION 表示多个联合作为一个结果集MATCH (person)-[:HAS_CAT]-(:Cat)} AS hasPetWITH 结合
外部范围的变量对整个子查询都是可见的即使使用WITH子句也是如此。为了避免混淆不允许隐藏这些变量。当内部作用域内新引入的变量用相同的变量定义时外部作用域变量将被遮蔽。在下面的示例中外部变量名被遮蔽因此会抛出错误。
WITH Peter as name
MATCH (person:Person {name: name})
WHERE EXISTS {WITH Ozzy AS nameMATCH (person)-[:HAS_DOG]-(d:Dog)WHERE d.name name
}
RETURN person.name AS name
// The variable name is shadowing a variable with the same name from the outer scope and needs to be renamed (line 4, column 20 (offset: 90))RETURN 结合
EXISTS子查询不需要在子查询的末尾使用RETURN子句。如果存在则不需要使用别名这与CALL子查询不同。EXISTS子查询返回的任何变量在该子查询之后都不可用。
MATCH (person:Person)
WHERE EXISTS {MATCH (person)-[:HAS_DOG]-(:Dog)RETURN person.name
}
RETURN person.name AS nameCOUNT 子查询
可以使用COUNT子查询表达式对子查询返回的行数进行计数。
任何非写查询都是允许的。COUNT子查询与常规查询的不同之处在于最终的RETURN子句可以省略因为在子查询中定义的任何变量在表达式之外都不可用即使使用了最终的RETURN子句。一个例外是对于DISTINCT UNION子句RETURN子句仍然是强制性的。
值得注意的是如果COUNT仅由一个模式和一个可选的where子句组成则可以在子查询中省略MATCH关键字。
简单 Count 子查询
MATCH (person:Person)
WHERE COUNT { (person)-[:HAS_DOG]-(:Dog) } 1 // count 关系
RETURN person.name AS nameCount中Where语句
MATCH (person:Person)
WHERE COUNT {(person)-[:HAS_DOG]-(dog:Dog)WHERE person.name dog.name //限定了 dog的name。
} 1
RETURN person.name AS nameCount中Union
MATCH (person:Person)
RETURNperson.name AS name,COUNT {MATCH (person)-[:HAS_DOG]-(dog:Dog)RETURN dog.name AS petName // dogUNIONMATCH (person)-[:HAS_CAT]-(cat:Cat)RETURN cat.name AS petName // cat} AS numPets // count (union结果集)Count 中 With
WITH Peter as name
MATCH (person:Person {name: name})
WHERE COUNT {WITH Ozzy AS name //变量名冲突MATCH (person)-[:HAS_DOG]-(d:Dog)WHERE d.name name
} 1
RETURN person.name AS nameMATCH (person:Person)
WHERE COUNT {WITH Ozzy AS dogName //新的变量MATCH (person)-[:HAS_DOG]-(d:Dog)WHERE d.name dogName
} 1
RETURN person.name AS nameCount在其他语句
MATCH (person:Person)
RETURN person.name, COUNT { (person)-[:HAS_DOG]-(:Dog) } as howManyDogs //统计dogMATCH (person:Person) WHERE person.name Andy
SET person.howManyDogs COUNT { (person)-[:HAS_DOG]-(:Dog) } //设置dog 数量
RETURN person.howManyDogs as howManyDogsMATCH (person:Person)
RETURNCASEWHEN COUNT { (person)-[:HAS_DOG]-(:Dog) } 1 THEN Doglover person.nameELSE person.nameEND AS resultMATCH (person:Person)
RETURN COUNT { (person)-[:HAS_DOG]-(:Dog) } AS numDogs, //作为 Group key。avg(person.age) AS averageAgeORDER BY numDogsCOLLECT 子查询
可以使用COLLECT子查询表达式创建一个包含给定子查询返回的行的列表。返回的数据类型是个List。
简单Collect子查询
MATCH (person:Person)
WHERE Ozzy IN COLLECT { MATCH (person)-[:HAS_DOG]-(dog:Dog) RETURN dog.name } //类似 SQL 中的 in。
RETURN person.name AS nameCollect结合Where
MATCH (person:Person)
RETURN person.name as name, COLLECT {MATCH (person)-[r:HAS_DOG]-(dog:Dog)WHERE r.since 2017RETURN dog.name
} as youngDogs //返回的是个List[]。Collect结合Union
MATCH (person:Person)
RETURNperson.name AS name,COLLECT {MATCH (person)-[:HAS_DOG]-(dog:Dog)RETURN dog.name AS petNameUNION // 类似 SQL union结果集MATCH (person)-[:HAS_CAT]-(cat:Cat)RETURN cat.name AS petName} AS petNames //返回的是个List[]。Collect 结合 WITH
MATCH (person:Person)
RETURN person.name AS name, COLLECT {WITH 2018 AS yearOfTheDog //定义 变量MATCH (person)-[r:HAS_DOG]-(d:Dog)WHERE r.since yearOfTheDogRETURN d.name
} as dogsOfTheYear //返回的是个List[]。Collect在其他语句
MATCH (person:Person) WHERE person.name Peter
SET person.dogNames COLLECT { MATCH (person)-[:HAS_DOG]-(d:Dog) RETURN d.name }
RETURN person.dogNames as dogNamesMATCH (person:Person)
RETURNCASEWHEN COLLECT { MATCH (person)-[:HAS_DOG]-(d:Dog) RETURN d.name } [] THEN No Dogs person.nameELSE person.nameEND AS resultMATCH (person:Person)
RETURN COLLECT { MATCH (person)-[:HAS_DOG]-(d:Dog) RETURN d.name } AS dogNames, //作为 group keyavg(person.age) AS averageAgeORDER BY dogNamesCOLLECT vs collect()
Collect() 会移除 null。collect{}不移除null如果需要移除要加过滤条件。
MATCH (p:Person)
RETURN collect(p.nickname) AS names
// [Pete, Tim]
RETURN COLLECT {MATCH (p:Person)RETURN p.nickname ORDER BY p.nickname} AS names
//[Pete, Tim, null]RETURN COLLECT {MATCH (p:Person)WHERE p.nickname IS NOT NULL // 过滤条件。RETURN p.nickname ORDER BY p.nickname} AS names
// [Pete, Tim]type断言表达式
expr IS :: TYPEUNWIND [42, true, abc] AS val
RETURN val, val IS :: INTEGER AS isInteger//从变量里每个元素都进行判断。
val isInteger
42 true
true false
abc false
// NOT
UNWIND [42, true, abc] AS val
RETURN val, val IS NOT :: STRING AS notString
// IS :: returns true for all expressions evaluating to null
toFloat(null) IS :: BOOLEAN // true。
// IS NOT :: returns false for all expressions evaluating to null
(null 1) IS NOT :: DATE // false//属性断言
MATCH (n:Person)
WHERE n.age IS :: INTEGER AND n.age 18
RETURN n.name AS name, n.age AS ageCypher将把任何精确的数值参数视为INTEGER而不管其声明的大小。 同义词
expr IS TYPED TYPE
expr :: TYPE
expr IS NOT TYPED TYPEANY 、NOTHING
ANY是一个超类型它匹配所有类型的值。NOTHING是包含一组空值的类型。这意味着它对所有值返回false。
RETURN 42 IS :: ANY AS isOfTypeAny, 42 IS :: NOTHING AS isOfTypeNothing
//true falseLIST类型
UNWIND [[42], [42, null], [42, 42.0]] as val
RETURN val, val IS :: LISTINTEGER AS isIntList //注意LIST 的 内部类型类似JAVA 泛型
//
[42] true
[42, null] true
[42, 42.0] false //42.0不是INTEGER空列表匹配任何内部类型包括NOTHING。 RETURN[] IS :: LISTNOTHING AS isNothingList, //TRUE[] IS :: LISTINTEGER AS isIntList, // true[] IS :: LISTFLOAT NOT NULL AS isFloatNotNullList //true标签表达式
在早期版本的Neo4j中节点的标签表达式只有一个冒号操作符表示AND操作符。随着版本5的发布除了单个冒号操作符之外还引入了一个带有扩展逻辑操作符集的新标签表达式。重要的是要注意不能混合使用这些不同类型的标签表达式语法。
当应用于节点的标签集时标签表达式的计算结果为true或false。假设没有应用其他筛选器那么求值为true的标签表达式表示匹配该节点。
NodeLabel expression()(:A)(:B)(:C)(:A:B)(:A:C)(:B:C)(:A:B:C)()√√√√√√√√(:A)√√√√(:AB)√√(:A|B)√√√√√√(:!A)√√√√(:!!A)√√√√(:A!A)(:A|!A)√√√√√√√√(:%)√√√√√√√(:!%)√(:%|!%)√√√√√√√√(:%!%)(:A%)√√√√(:A|%)√√√√√√√(:(AB)!(BC))√(:!(A%)%)√√√
语法
没有标签MATCH (n)单个标签MATCH (n:A)ANDMATCH (n:AB)ORMATCH (n:A|B)NOTMATCH (n:!A)通配符MATCH (n:%) 至少一个标签嵌套LableMATCH (n:(!A!B)|C)WHEREMATCH (n) WHERE n:A|BWITH,RETURNMATCH (n) RETURN n:AB
关系类型表达式
关系必须有准确的一种类型。例如模式(a)-[r:RQ]-(b)或(a)-[r:!%]-(b)永远不会返回任何结果。
变长关系只能有由|组成的关系类型表达式。这意味着()-[r:!R*]-()是不允许的,而 ()-[r:Q|R*]-()是允许的。
关系关系类型表达式[:A][:B][:C][]√√√[:A]√[:AB][:A|B]√√[:!A]√√[:!!A]√[:A!A][:A|!A]√√√[:%]√√√[:!%][:%|!%]√√√[:%!%][:A%]√[:A|%]√√√
标签表达式不能与标签语法结合使用。例如:A:BC将抛出错误。相反使用:ABC或:A:B:C。
语法 没有标签MATCH ()-[r]-() 单个标签MATCH ()-[r:R1]-() ORMATCH ()-[r:R1|R2]-() NOTMATCH ()-[r:!R1]-() 嵌套LableMATCH ()-[r:(!R1!R2)|R3]-() WHEREMATCH (n)-[r]-(m) WHERE r:R1|R2 WITH,RETURNMATCH (n)-[r]-(m) RETURN r:R1|R2 AS result CASE MATCH (n)-[r]-(m)
RETURN
CASEWHEN n:AB THEN 1WHEN r:!R1!R2 THEN 2ELSE -1
END AS result没有AND因为AND不返回任何结果 参数
Cypher支持带参数查询。参数化查询是一种查询其中占位符用于参数并在执行时提供参数值。这意味着开发人员不必借助字符串构建来创建查询。此外参数使Cypher更容易缓存执行计划从而加快查询执行时间。
参数可用于: 字面量和表达式 节点和关系id
参数不能用于以下结构因为它们构成了编译成查询计划的查询结构的一部分:
属性keyMATCH (n) WHERE n.$param something关系类型 MATCH (n)-[:$param]→(m)标签 (n:$param)
参数可以由字母和数字组成也可以由字母和数字的任意组合组成但不能以数字或货币符号开头。
在运行查询时设置参数取决于客户端环境。例如: Shell环境 :param name Joe Neo4j Browser :param name Joe 驱动根据语言 Neo4j HTTP API
参数以JSON格式给出提交它们的确切方式取决于所使用的驱动程序。
Auto-parameterization
从版本5开始即使查询是部分参数化的Cypher也会尝试推断参数。查询中的每个文字都被一个参数替换。这增加了计算计划的可重用性这些查询除了字面量之外都是相同的。不建议依赖这种行为——用户应该在他们认为合适的地方使用参数。
字符串字面量
// 参数
{name: Johan
}
//用法1
MATCH (n:Person)
WHERE n.name $name
RETURN n
//用法2
MATCH (n:Person {name: $name})
RETURN n正则表达式
//输入参数
{regex: .*h.*
}
//用法
MATCH (n:Person)
WHERE n.name ~ $regex
RETURN n.name字符串
MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name
使用属性创建节点
{props: {name: Andy,position: Developer}
}CREATE ($props)创建多个节点
{props: [ {awesome: true,name: Andy,position: Developer}, {children: 3,name: Michael,position: Developer} ]
}UNWIND $props AS properties //把属性展开
CREATE (n:Person)
SET n properties //赋值所有属性
RETURN nset属性
{props: {name: Andy,position: Developer}
}MATCH (n:Person)
WHERE n.name Michaela
SET n $propsSKIP LIMIT
{s: 1,l: 1
}
//
MATCH (n:Person)
RETURN n.name
SKIP $s //
LIMIT $l //node id
//单id
{ id : 4:1fd57deb-355d-47bb-a80a-d39ac2d2bcdb:0}
MATCH (n)
WHERE elementId(n) $id
RETURN n.name
//多id
{ids : [ 4:1fd57deb-355d-47bb-a80a-d39ac2d2bcdb:0, 4:1fd57deb-355d-47bb-a80a-d39ac2d2bcdb:1 ]
}
MATCH (n)
WHERE elementId(n) IN $ids
RETURN n.name方法调用
{indexname : My_index
}
CALL db.resampleIndex($indexname)操作符
Operators at a glance
操作符类型聚合操作符DISTINCT属性操作符. 静态属性访问 [] 动态属性访问 替换节点或属性的全部属性 修改已存在属性新增不存在属性数学操作符, -, *, /, %, ^比较操作符, , , , , , IS NULL, IS NOT NULL字符串特定操作符STARTS WITH, ENDS WITH, CONTAINS, ~ (正则匹配)逻辑操作符AND, OR, XOR, NOT字符串操作符 (字符串连接)时间操作符 and - for operations between durations and temporal instants/durations, * and / for operations between durations and numbersmap操作符. 静态key访问, []动态key访问List操作符连接List所有元素放一个List IN List是否存在元素 []动态访问元素
注释
Cypher使用 // 来记性注释。
MATCH (n) RETURN n //This is an end of line comment子句
Match
MATCH (n) //匹配所有节点
MATCH (movie:Movie) //匹配指定节点
// 关联节点
MATCH (director {name: Oliver Stone})--(movie) //关联的任意节点
RETURN movie.title MATCH (:Person {name: Oliver Stone})--(movie:Movie) //关联到movie
RETURN movie.title
关系
//出关系--
MATCH (:Person {name: Oliver Stone})--(movie)
RETURN movie.title
//无方向关系
MATCH (a)-[:ACTED_IN {role: Bud Fox}]-(b)
RETURN a, b
//多关系
MATCH (wallstreet {title: Wall Street})-[:ACTED_IN|DIRECTED]-(person)
RETURN person.name关系深度
在单个模式中关系只匹配一次。在关系独特性一节中了解更多。
关系类型一般用字母数字混合命名如果有特殊字符需用反引号( )括起来。eg(rob)-[:OLD FRIENDS]-(martin)。
// 2层关系
MATCH (charlie {name: Charlie Sheen})-[:ACTED_IN]-(movie)-[:DIRECTED]-(director)
RETURN movie.title, director.nameOPTIONAL MATCH
OPTIONAL MATCH 与Match模式基本类似唯一差别是如果没有匹配上则用null 表示类似于SQL中的Outer Join。
Cypher中的查询是作为管道运行的。如果一个子句没有返回结果它将有效地结束查询因为后续子句将没有数据可执行。
//不会返回结果。
MATCH (a:Person {name: Martin Sheen})
MATCH (a)-[r:DIRECTED]-() //没有匹配则不会执行下一步。
RETURN a.name, r
//会返回结果。
MATCH (p:Person {name: Martin Sheen})
OPTIONAL MATCH (p)-[r:DIRECTED]-() //没有匹配则返回null。
RETURN p.name, r //OUTER JOINp 是有值的空Node用null表示。Optional 关系
MATCH (a:Person {name: Charlie Sheen})
OPTIONAL MATCH (a)--(x)
RETURN x //返回 nullOptional元素的属性
如果元素返回null则元素的属性也返回null。不会抛出空指针。
MATCH (a:Movie {title: Wall Street})
OPTIONAL MATCH (a)--(x)
RETURN x, x.name //返回null null Optional 命名关系
MATCH (a:Movie {title: Wall Street})
OPTIONAL MATCH (a)-[r:ACTED_IN]-()
RETURN a.title, r // 关系返回 null。MATCH (a:Movie {title: Wall Street})
OPTIONAL MATCH (x)-[r:ACTED_IN]-(a)
RETURN a.title, x.name, type(r) // 返回的是ACTED_IN不是null。注意虽然关系r 返回null但是type® 返回的是ACTED_IN。 RETURN
MATCH p (keanu:Person {name: Keanu Reeves})-[r]-(m)
RETURN * //返回所有元素。即所有匹配的变量pkeanurm含有特殊字符的变量名使用反引号( )括起来。
列别名使用 AS egRETURN p.nationality AS citizenship
Optional 属性
如果一个元素没有指定的属性则返回null。
其他表达式
RETURN m.released 2012, Im a literal,[p(m)--() | p] AS (m)--()结果去重
MATCH (p:Person {name: Keanu Reeves})--(m)
RETURN DISTINCT mWITH
WITH子句允许将查询部分链接在一起将一个查询部分的结果作为下一个查询部分的起点或标准。
重要的是要注意WITH影响作用域中的变量。没有包含在WITH子句中的任何变量都不会转移到查询的其余部分。通配符*可用于包含当前范围内的所有变量。
使用WITH您可以在将输出传递给后续查询部分之前对其进行操作。可以对结果集中的项的Shape和(或)数量进行操作。
WITH的一种常见用法是限制传递给其他MATCH子句的条目数量。通过组合ORDER By和LIMIT可以根据某些条件获得前X个条目然后从图中引入额外的数据。
WITH还可以用于引入包含表达式结果的新变量以供后续查询部分使用。为方便起见通配符*扩展为当前范围内的所有变量并将它们携带到下一个查询部分。
另一个用途是对聚合值进行过滤。WITH用于引入聚合然后在WHERE中的谓词中使用聚合。这些聚合表达式在结果中创建新的绑定。
WITH还用于分离图的读取和更新。查询的每个部分必须是只读的或只写的。当从写部分切换到读部分时必须使用with子句进行切换。
引入变量
MATCH (george {name: George})--(otherPerson)
WITH otherPerson, toUpper(otherPerson.name) AS upperCaseName //upperCaseName 新变量
WHERE upperCaseName STARTS WITH C
RETURN otherPerson.name通配符扩展
MATCH (person)-[r]-(otherPerson)
WITH *, type(r) AS connectionType //把几个变量携带下去。personrotherPerson
RETURN person.name, otherPerson.name, connectionType过滤聚合结果
MATCH (david {name: David})--(otherPerson)--()
WITH otherPerson, count(*) AS foaf //聚合 COUNT
WHERE foaf 1 //过滤类似SQL HAVING
RETURN otherPerson.name结果排序
MATCH (n)
WITH n
ORDER BY n.name DESC
LIMIT 3
RETURN collect(n.name)分支限制
可以匹配路径限制到一定数量然后使用这些路径作为基础再次匹配以及任意数量的类似有限搜索。
MATCH (n {name: Anders})--(m)
WITH m //从这个地方开始对m进行限制
ORDER BY m.name DESC
LIMIT 1 //返回第一个记录
MATCH (m)--(o) //基于返回的记录再进行匹配。
RETURN o.name限制后过滤
UNWIND [1, 2, 3, 4, 5, 6] AS x
WITH x
LIMIT 5 //先限制
WHERE x 2 //再过滤
RETURN xUNWIND
展开List的元素。
UNWIND [1, 2, 3, null] AS x //结果为4行记录1,2,3,null
UNWIND [] AS empty //返回0行记录。
UNWIND null AS x //展开一个非List元素返回0行记录
UNWIND $events AS event //可以对参数进行展开WHERE
WHERE子句本身并不是一个子句— —相反它是MATCH、OPTIONAL MATCH和WITH子句的一部分。
当与MATCH和OPTIONAL MATCH一起使用时WHERE会向所描述的模式添加约束。在匹配完成后它不应该被视为一个过滤器。然而在WITH的情况下WHERE只是过滤结果。
在有多个MATCH / OPTIONAL MATCH子句的情况下WHERE中的谓词总是最为最接近的前面的MATCH / OPTIONAL MATCH中的模式的一部分。如果将WHERE放在错误的MATCH子句中结果和性能都可能受到影响。
//节点模式断言
WITH 30 AS minAge
MATCH (a:Person WHERE a.name Andy)-[:KNOWS]-(b:Person WHERE b.age minAge)
RETURN b.name
///约束Label 1
MATCH (a:Person {name: Andy})
RETURN [(a)--(b WHERE b:Person) | b.name] AS friends //约束b。
//boolean操作
MATCH (n:Person)
WHERE n.name Peter XOR (n.age 30 AND n.name Timothy) OR NOT (n.name Timothy OR n.name Peter)
RETURNn.name AS name,n.age AS age
ORDER BY name
//约束Label 2
MATCH (n)
WHERE n:Swedish
RETURN n.name, n.age
//约束节点属性
MATCH (n:Person)
WHERE n.age 30
RETURN n.name, n.age
//约束关系属性
MATCH (n:Person)-[k:KNOWS]-(f)
WHERE k.since 2000
RETURN f.name, f.age, f.email
//约束动态节点属性
WITH AGE AS propname
MATCH (n:Person)
WHERE n[toLower(propname)] 30
RETURN n.name, n.age
//约束关系
WITH 2000 AS minYear
MATCH (a:Person)-[r:KNOWS WHERE r.since minYear]-(b:Person)
RETURN r.since与With一起使用
MATCH (n:Person)
WITH n.name as name
WHERE n.age 25
RETURN name字符串匹配
MATCH (n:Person)
WHERE n.name STARTS WITH PetWHERE n.name ENDS WITH terWHERE n.name CONTAINS eteWHERE NOT n.name ENDS WITH yWHERE n.name ~ Tim.*WHERE n.email ~ .*\\.comWHERE n.name ~ (?i)AND.* //大小写不敏感路径模式约束
模式是Cypher中的表达式它返回一个路径列表。列表表达式也是谓词;空列表表示false非空列表表示true。
模式不仅是表达式也是谓词。模式的唯一限制是它必须能够在单一路径中表达它。与MATCH不同不能在多个路径之间使用逗号。要使用WHERE组合多个模式请使用AND。注意不能引入新的变量。尽管它可能看起来与MATCH模式非常相似但WHERE子句用于消除匹配的路径。MATCH (a)-[]→(b)与WHERE (a)-[]→(b)非常不同。前者将为它能找到的a和b之间的每一条路径生成一条路径而后者将消除a和b之间没有直接关系链的任何匹配路径。
MATCH(timothy:Person {name: Timothy}),(other:Person)
WHERE other.name IN [Andy, Peter] AND (other)--(timothy) //约束关系。
RETURN other.name, other.ageORDER BY
ORDER BY是RETURN或WITH后续的子句它指定输出应该排序以及如何排序。
MATCH (n)
WITH n ORDER BY n.age
RETURN collect(n.name) AS namesORDER BY 可以基于表达式结果排序。
MATCH (n)
RETURN n.name, n.age, n.length
ORDER BY keys(n) //keysSKIP,LIMIT
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 1
LIMIT 2可以基于表达式结果
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 1 toInteger(3*rand())CREATE
创建Node
CREATE (n) //创建单个节点
CREATE (n), (m) //创建多个节点
CREATE (n:Person)
CREATE (n:Person:Swedish)
CREATE (n:Person {name: Andy, title: Developer})// 创建的节点定义个变量后续引用
CREATE (a {name: Andy})
RETURN a.name创建关系
MATCH(a:Person),(b:Person)
WHERE a.name A AND b.name B
CREATE (a)-[r:RELTYPE {name: a.name - b.name}]-(b) //创建关系并设置属性。
RETURN type(r), r.name
//一个路径
CREATE p (:Person {name:Andy})-[:WORKS_AT]-(:Company {name: Neo4j})-[:WORKS_AT]-(:Person {name: Michael})
RETURN pDELETE
MATCH (n:Person {name: Laurence Fishburne})-[r:ACTED_IN]-()
DELETE r
//删除节点并删除它的关系
MATCH (n:Person {name: Carrie-Anne Moss})
DETACH DELETE n //关系一起删除SET
MATCH (n {name: Andy})
SET n.surname Taylor //设置属性
RETURN n.name, n.surnameMATCH (n {name: Andy})
SET n.surname Taylor //设置属性
RETURN n.name, n.surname
//移除属性
MATCH (n {name: Andy})
SET n.name null //null
RETURN n.name, n.age
//替换所有属性
MATCH (p {name: Peter})
SET p {name: Peter Smith, position: Entrepreneur}
RETURN p.name, p.age, p.position
//移除所有属性
MATCH (p {name: Peter})
SET p {}
RETURN p.name, p.age操作属性
使用map和改变特定属性 map中不在节点或关系上的任何属性都将被添加。 map中不在节点或关系上的任何属性将保持原样。 map和节点或关系中的任何属性都将在节点或关系中被替换。但是如果映射中的任何属性为null则将从节点或关系中删除该属性。
MATCH (p {name: Peter})
SET p {age: 38, hungry: true, position: Entrepreneur}
RETURN p.name, p.age, p.hungry, p.positionREMOVE
//移除属性
MATCH (a {name: Andy})
REMOVE a.age
RETURN a.name, a.age
//移除 Label
MATCH (n {name: Peter})
REMOVE n:German
RETURN n.name, labels(n)FOREACH
FOREACH子句用于更新集合中的数据无论是路径的组件还是聚合的结果。
FOREACH括号内的变量上下文与其外部的变量上下文是分开的。这意味着如果在FOREACH语句中创建节点变量则不能在FOREACH语句之外使用它除非进行匹配才能找到它。
在FOREACH括号内您可以执行任何更新命令:SET、REMOVE、CREATE、MERGE、DELETE和FOREACH。
MATCH p(start)-[*]-(finish)
WHERE start.name A AND finish.name D
FOREACH (n IN nodes(p) | SET n.marked true)MERGE
MERGE子句要么匹配图中的现有节点模式并绑定它们要么(如果不存在)创建新数据并绑定它。通过这种方式它充当MATCH和CREATE的组合允许根据是否匹配或创建指定数据执行特定操作。 出于性能原因强烈建议在使用MERGE时在标签或属性上创建模式索引。 当对完整模式使用MERGE时行为是要么匹配整个模式要么创建整个模式。MERGE不会部分地使用现有模式。如果需要部分匹配可以通过将模式拆分为多个MERGE子句来实现。 在并发更新下MERGE只保证MERGE模式的存在而不保证唯一性。为了保证具有某些属性的节点的唯一性应该使用属性唯一性约束。 与MATCH类似MERGE可以匹配模式的多次出现。如果有多个匹配项它们都将被传递到查询的后面阶段。
MERGE子句的最后一部分是ON CREATE和(或)ON MATCH操作符。这允许查询表达对节点或关系属性的附加更改具体取决于元素是在数据库中匹配(MATCH)还是创建(CREATE)。
MERGE (robert:Critic)
RETURN robert, labels(robert)MERGE (charlie {name: Charlie Sheen, age: 10})
RETURN charlieMERGE (michael:Person {name: Michael Douglas})
RETURN michael.name, michael.bornInMATCH (person:Person)
MERGE (location:Location {name: person.bornIn}) // 引用person的属性
RETURN person.name, person.bornIn, locationON CREATE 和ON MATCH
Merge事件触发器
MERGE (keanu:Person {name: Keanu Reeves, bornIn: Beirut, chauffeurName: Eric Brown})
ON CREATESET keanu.created timestamp() //创建时set 创建时间
RETURN keanu.name, keanu.createdMERGE (person:Person)
ON MATCHSET person.found true //可以设置多个属性的。
RETURN person.name, person.foundMERGE (keanu:Person {name: Keanu Reeves})
ON CREATESET keanu.created timestamp()
ON MATCHSET keanu.lastSeen timestamp()
RETURN keanu.name, keanu.created, keanu.lastSeen//直接关系
MATCH(charlie:Person {name: Charlie Sheen}),(wallStreet:Movie {title: Wall Street})
MERGE (charlie)-[r:ACTED_IN]-(wallStreet)
RETURN charlie.name, type(r), wallStreet.title
//非直接关系
MATCH(charlie:Person {name: Charlie Sheen}),(oliver:Person {name: Oliver Stone})
MERGE (charlie)-[r:KNOWS]-(oliver)
RETURN rMATCH (person:Person)
MERGE (person)-[r:HAS_CHAUFFEUR]-(chauffeur:Chauffeur {name: person.chauffeurName})//引用变量
RETURN person.name, person.chauffeurName, chauffeurCALL
CALL { }
以RETURN语句结束的子查询称为返回子查询而没有RETURN语句的子查询称为单元子查询。
对每个输入行求值一个子查询。返回子查询的每个输出行都与输入行组合以构建子查询的结果。这意味着返回的子查询将影响行数。如果子查询不返回任何行则子查询之后将没有行可用。
另一方面调用单元子查询是因为它们的副作用(即只用于修改而不用于返回)而不是因为它们的结果因此不会影响封闭查询的结果。
子查询({}中的子句)如何与封闭查询(外面的子句)交互是有限制的: 子查询只能引用封闭查询中的变量如果它们是显式导入的。 子查询不能返回与封闭查询中的变量名称相同的变量。 从子查询返回的所有变量随后都可以在封闭查询中使用。
UNWIND [0, 1, 2] AS x
CALL { //子查询MATCH (n:Counter)SET n.count n.count 1RETURN n.count AS innerCount //返回的变量
}
WITH innerCount
MATCH (n:Counter)
RETURNinnerCount,n.count AS totalCountPost-union
CALL {MATCH (p:Person)RETURN pORDER BY p.age ASCLIMIT 1
UNION //返回结果集MATCH (p:Person)RETURN pORDER BY p.age DESCLIMIT 1
}
RETURN p.name, p.age
ORDER BY p.name事务
LOAD CSV FROM file:///friends.csv AS line
CALL {WITH lineCREATE (:Person {name: line[1], age: toInteger(line[2])})
} IN TRANSACTIONSMATCH (n)
CALL {WITH nDETACH DELETE n
} IN TRANSACTIONS事务批次处理
可以根据提交当前事务和开始新事务之前要处理的输入行数来指定每个单独事务中要完成的工作量。输入行数是用of n rows(或of n ROW)修饰符设置的。如果省略默认批处理大小为1000行。行数可以使用计算结果为正整数且不引用节点或关系的任何表达式来表示。
LOAD CSV FROM file:///friends.csv AS line
CALL {WITH lineCREATE (:Person {name: line[1], age: toInteger(line[2])})
} IN TRANSACTIONS OF 2 ROWS //2行一个事务异常处理
用户可以从三个不同的选项标志中选择一个来控制在CALL{…}中的事务:
ON ERROR CONTINUE忽略可恢复的错误并继续执行后续的内部事务。外部事务成功。它将导致来自失败的内部查询的预期变量被绑定为该特定事务的空值。
ON ERROR BREAK忽略可恢复的错误并停止后续内部事务的执行。外部事务成功。它将导致来自失败内部查询的预期变量被绑定为空用于所有后续事务(包括失败的事务)。
ON ERROR FAIL不能确认可恢复的错误并停止后续内部事务的执行。外部事务失败。如果没有显式指定标志这是默认行为。
UNWIND [1, 0, 2, 4] AS i
CALL {WITH iCREATE (n:Person {num: 100/i}) // Note, fails when i 0RETURN n
} IN TRANSACTIONSOF 1 ROWON ERROR CONTINUE
RETURN n.num;状态报告
可以使用report status作为变量来报告内部事务的执行状态这个标志在ON ERROR FAIL时是不允许的。每次内部查询执行完成后(无论成功与否)都会创建一个状态值记录有关执行和执行它的事务的信息:
如果内部执行产生一行或多行作为输出则在所选变量名称下向每一行添加到此状态值的绑定。
如果内部执行失败则生成单行其中包含到所选变量下的此状态值的绑定以及内部查询(如果有的话)应该返回的所有变量的空绑定。
状态值是一个Map值包含以下字段:
Started:内部事务启动时为true否则为false。Committed当内部事务更改成功提交时为true否则为false。transactionId:内部事务id如果事务没有启动则为空。errorMessage内部事务错误消息如果没有错误则为null。
UNWIND [1, 0, 2, 4] AS i
CALL {WITH iCREATE (n:Person {num: 100/i}) // Note, fails when i 0RETURN n
} IN TRANSACTIONSOF 1 ROWON ERROR CONTINUEREPORT STATUS AS s
RETURN n.num, s;限制 嵌套的CALL{…}子句不受支持。 不支持UNION中的IN TRANSACTIONS。 不支持在写子句之后的IN TRANSACTIONS除非该写子句是在CALL{…}中。
另外当在CALL子查询中使用 WITH子句时有一些限制: 只有通过with子句导入的变量才能被使用。 在导入的WITH子句中不允许使用表达式或别名。 不可能在导入WITH子句之后加上以下任何子句:DISTINCT、ORDER BY、WHERE、SKIP和LIMIT。
CALL 方法
UNION
USE
Load CSV CSV文件的URL是通过使用FROM指定的后面跟着一个URL的任意表达式。 需要使用AS为CSV数据指定一个变量。 CSV文件可以存储在数据库服务器上然后使用file:/// URL访问。另外LOAD CSV还支持通过HTTPS、HTTP和FTP访问CSV文件。 LOAD CSV支持使用gzip和Deflate压缩的资源。此外LOAD CSV支持本地存储的CSV文件压缩与ZIP。 LOAD CSV将遵循HTTP重定向但出于安全原因它不会遵循更改协议的重定向例如如果重定向从HTTPS转到HTTP。 LOAD CSV通常与查询子句CALL{…}in TRANSACTIONS一起使用。
文件URLs配置
dbms.security.allow_csv_import_from_file_urls是否支持 file:/// 协议。默认true。
server.directories.importfile:/// 文件的根目录仅对本地文件有效。
CSV文件格式 字符编码为UTF-8 结束行终止取决于系统例如在Unix上是\n在windows上是\r\n; 默认的字段结束符是, 字段结束符可以通过使用LOAD CSV命令中的FIELDTERMINATOR选项来更改; CSV文件中允许使用带引号的字符串并且在读取数据时删除引号; 字符串引号的字符是双引号 如果dbms.import.csv.legacy_quote_escaping设置为默认值true \用作转义字符; 双引号必须位于带引号的字符串中并使用转义字符或第二个双引号进行转义。
导入
LOAD CSV FROM file:///artists.csv AS line //给每行命名一个变量
CREATE (:Artist {name: line[1], year: toInteger(line[2])}) //变量通过[]引用属性LOAD CSV FROM https://data.neo4j.com/bands/artists.csv AS line
CREATE (:Artist {name: line[1], year: toInteger(line[2])})
//第一行为列头 WITH HEADERS
LOAD CSV WITH HEADERS FROM file:///artists-with-headers.csv AS line
CREATE (:Artist {name: line.Name, year: toInteger(line.Year)})
//自定义 字段分隔符
LOAD CSV FROM file:///artists-fieldterminator.csv AS line FIELDTERMINATOR ;
CREATE (:Artist {name: line[1], year: toInteger(line[2])})//事务支持
LOAD CSV FROM file:///artists.csv AS line
CALL {WITH lineCREATE (:Artist {name: line[1], year: toInteger(line[2])})
} IN TRANSACTIONS
//linenumber() 返回行记录
LOAD CSV FROM file:///artists.csv AS line
RETURN linenumber() AS number, line
// file() 获取文件path
LOAD CSV FROM file:///artists.csv AS line
RETURN DISTINCT file() AS pathSHOW
SHOW [ALL|BUILT IN|USER DEFINED] FUNCTION[S]
[YIELD { * | field[, ...] } [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]
[WHERE expression]
[RETURN field[, ...] [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]SHOW PROCEDURE[S]
[YIELD { * | field[, ...] } [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]
[WHERE expression]
[RETURN field[, ...] [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]SHOW SETTING[S] [setting-name[,...]]
[YIELD { * | field[, ...] } [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]
[WHERE expression]
[RETURN field[, ...] [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]SHOW TRANSACTION[S] [transaction-id[,...]]
[YIELD { * | field[, ...] } [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]
[WHERE expression]
[RETURN field[, ...] [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]TERMINATE TRANSACTION[S] transaction_id[, ...]
[YIELD { * \| field[, ...] }[ORDER BY field[, ...]][SKIP n][LIMIT n][WHERE expression][RETURN field[, ...] [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]
]节点变量 (Node variables)
如果我们以后想要引用某个节点我们可以给它一个变量比如§代表person或者(t)代表thing。
如果节点与返回的结果不相关可以使用空括号()指定一个匿名节点。这意味着您不能在稍后的查询中返回此节点。
节点标签 (Node labels)
如果您还记得属性图数据模型还可以通过分配节点标签将相似的节点分组在一起。标签允许你指定要查找或创建的特定类型的实体。在我们的示例中Person、Technology和Company是标签。
你可以把这想象成告诉SQL在哪个表中查找特定的行。就像告诉SQL从person或Employee或Customer表中查询一个人的信息一样您也可以告诉Cypher只检查这些信息的标签。这有助于Cypher区分实体并优化查询的执行。在可能的情况下在查询中使用节点标签总是更好。 不指定标签则会查询所有节点性能会严重下降。 () //匿名节点(no label or variable) 后面不能引用
(p:Person) //using variable p and label Person
(:Technology) //no variable, label Technology
(work:Company) //using variable work and label Company关系类型 (Relationship types)
关系类型对关系进行分类并添加意义类似于标签对节点进行分组的方式。在我们的属性图数据模型中关系表示节点如何相互连接和关联。通常可以通过查找动作或动词来识别数据模型中的关系。
[:LIKES] - makes sense when we put nodes on either side of the relationship (Sally LIKES Graphs)
[:IS_FRIENDS_WITH] - makes sense when we put nodes with it (Sally IS_FRIENDS_WITH John)
[:WORKS_FOR] - makes sense with nodes (Sally WORKS_FOR Neo4j)关系变量 (Relationship variables)
想在查询的后面引用一个关系我们可以给它一个变量比如[r]或[rel]。如果以后不需要引用该关系则可以使用两个破折号--, --, --指定匿名关系。
例如您可以使用-[rel]-或-[rel:LIKES]-并在稍后的查询中调用rel变量来引用关系及其详细信息。 如果您忘记了关系类型前面的冒号(:)例如-[LIKES]-它表示一个变量(而不是关系类型)。由于没有声明关系类型Cypher搜索所有类型的关系。 节点或关系属性 (Node or relationship properties)
属性是名称-值对它为节点和关系提供了额外的细节。在Cypher中我们可以在节点的括号内或关系的括号内使用花括号。然后将属性的名称和值放入花括号内。我们的示例图有一个节点属性(name)和一个关系属性(since)。
Node property: (p:Person {name: Sally})
Relationship property: -[rel:IS_FRIENDS_WITH {since: 2018}]-属性可以具有各种数据类型的值。
Cypher模式
节点和关系构成了图形模式的构建块。这些构建块可以组合在一起来表达简单或复杂的模式。模式是图最强大的功能。在Cypher中它们可以写成连续的路径也可以分成更小的模式并用逗号连接在一起。
要在Cypher中显示模式需要将目前所学的节点和关系语法结合起来。
在Cypher中该模式类似于下面的代码。
(p:Person {name: Sally})-[rel:LIKES]-(g:Technology {type: Graphs})普通
:guide cypher #
附录
参考
导入数据https://neo4j.com/docs/getting-started/data-import/
Cypher https://neo4j.com/docs/cypher-manual/current/introduction/