Start the command
neo4j console
Cypher syntax consists of four distinct parts, each with a specific rule:
start - Find the starting node in the graph.
match - match graph pattern, which can locate subgraphs of data of interest.
where - filter data based on some criteria.
return - returns the result of interest.
Query graph view (node-to-node direct relationship graph)
查询图谱视图(节点直接及相互关系)
CALL db.schema.visualization()
1. Create a node
-- 创建类型为Person,属性为 {id: 1,name:'盘古',birthday:date("2000-08-18")} 的节点
create(n:Person{id: 1,name:'盘古',birthday:date("2000-08-18")})return n
create(:`Person`{id: 100,name:'测试'})
-- 批量创建节点
create(n:Person{id: 2,name:'鸿钧',birthday:date("2000-08-20")}),
(:Person{id: 3,name:'太上老君',birthday:date("2000-08-21")})
-- 创建节点为Person 和 Power 顶点数据,即一个节拥有多个类型
create(:`Person`:`Power`{id: 100,name:'测试'})
-- 抽取所有结点中包含国家的的字段进行去重,用于创建国家节点数据
MATCH (n) WHERE (n.`国家`) IS NOT NULL
with
distinct n.`国家` AS gj
MERGE(g:`国家`{name:gj})
return g;
-- 批量创建
-- 使用unwind可以利用缓存进行快速创建大量数据,UNWIND只能对同一类型的数据进行处理
-- set n += p.properties 可以对任意个属性进行合并
UNWIND [
{name: 'Wang, Li', properties:{name: 'Wang, Li'}},
{name: 'zhangsan', properties:{name: 'zhangsan', age:'14'}}
] AS p
merge(n:`作者`{name: p.name}) set n += p.properties;
UNWIND $props AS p
match (n:文献{name: p.head}), (m:作者{name: p.tail})
create (n)-[:连接]->(m);
java create
/**
* 创建图结点数据
* 批量创建脚本 UNWIND $props AS p create(n:Person{name:'xx'})
*
* @param nodeList 结点数据
*/
private void createGraphNodeWithUnwind(List<DataNodeVO> nodeList) {
// 对数据信息分组处理,以 label 分组,因UNWIND只能对同一类型的数据进行处理
Map<String, List<DataNodeVO>> nodeGroupMap = nodeList.stream().collect(Collectors.groupingBy(r -> r.getLabel()));
List<DataNodeVO> groupRelation = null;
// 分批次处理关系
for (Map.Entry<String, List<DataNodeVO>> entity : nodeGroupMap.entrySet()) {
groupRelation = entity.getValue();
// 按照节点id进行分组,有些节点包含多属性
Map<String, List<DataNodeVO>> nodeIdGoupMap = groupRelation.stream().collect(Collectors.groupingBy(r -> r.getNodeId()));
List<Map<String, Object>> nodeDataList = new ArrayList<>(groupRelation.size());
List<DataNodeVO> dataNodes = null;
for (Map.Entry<String, List<DataNodeVO>> node : nodeIdGoupMap.entrySet()) {
dataNodes = node.getValue();
// 属性数据
Map<String, Object> properties = new HashMap<>(8);
dataNodes.stream().forEach(r -> {
properties.put(r.getProperty(), this.convertDataType(r.getDataType(), r.getPropertyValue()));
});
if (CollectionUtil.isNotEmpty(properties)) {
Map<String, Object> item = new HashMap<>(8);
item.put("label", entity.getKey());
item.put("name", properties.get(GraphConstants.DEFAULT_GRAPH_NODE_NAME));
item.put("properties", properties);
nodeDataList.add(item);
}
}
Map<String, Object> parameters = new HashMap<>(1);
parameters.put("props", nodeDataList);
// sql格式:UNWIND $props AS p create/merge(n:Person{name: p.name} set n += p.properties)
String relationSql = "UNWIND $props AS p merge(n:" + entity.getKey() + "{name: p.name}) set n += p.properties";
neo4jService.runTx(relationSql, parameters);
}
}
2. Query all data
-- 查询所有信息
MATCH (n) return n
-- 查询指定类型(Person和City)节点
MATCH (h:Person),(m:City) return h,m
-- 通过条件查询,查询主键id为0的节点,主键查询使用(),如果使用.则表示为属性
match(p:Person) where id(p)=0 return p
-- 通过属性查询,查询属性id=1 数据
match(p:Person) where p.id=1 return p
-- 查询指定数量
match(n:Person) return n limit 10
-- 模糊搜索
match(m:Movie) where m.name=~('.*大战.*') return m
-- 对所有结点的任何属性进行模糊搜索
match (n)
with n, [x in keys(n) WHERE n[x]=~'.*发.*'] as doesMatch
where size(doesMatch) > 0
return n
-- 对节点类型为'文献' 和 '作者' 的任何属性进行模糊搜索
match (n) where labels(n) in [['文献'],['作者']]
with n, [x in keys(n) WHERE n[x]=~'.*发.*'] as doesMatch
where size(doesMatch) > 0
return n
3. Modify entity
-- 修改主键id为1的Person的生日
match(p:Person) where id(p)=1 set p.birthday="2000-01-01" return p
-- 修改属性id为1的Person的生日
match(p:Person) where p.id=1 set p.birthday="1900-01-01" return p
-- 使用map赋值, 注意: 这样会清除所有原属性
match (p { name: 'Peter' })
set p = { name: 'Peter Smith', position: 'Entrepreneur' }
return p
-- 如果要保留原属性, 把=变成+=
match (p { name: 'Peter' })
set p += { name: 'Peter Smith', position: 'Entrepreneur' }
return p
-- 完全复制一个节点或者关系
-- SET可用于将所有属性从一个节点或关系复制到另一个节点. 目标节点或关系的原属性会被清空.
match (at { name: 'Andy' }),(pn { name: 'Peter' })
set at = pn
return at.name, at.age, at.hungry, pn.name, pn.age
-- 修改标签(label)
-- 修改一个
match (n { name: 'Stefan' })
set n:German
return n.name, labels(n) AS labels
-- 修改多个
match(n{name: 'Peter'})
set n:Swedish:Bossman
return n.name, labels(n) as labels
4. Delete
------------------ 只能删除不带连接的节点 start ---------------
-- 通过属性id删除数据
match(n:Person{id:1}) delete n
-- 通过条件删除,删除 主键id > 1的数据
MATCH (r) WHERE id(r) > 1 DELETE r
-- 删除 作者、文献、期刊所有节点
match(n:`作者`),(m:`文献`),(k:`期刊`) delete n,m,k
-- 删除属性
-- 删除 code 属性
match(d:`期刊`{name: '西北地质'}) remove d.code
-- 删除一个属性
-- 将这个属性置为null, 就是删除一个属性, 如下
match (n { name: 'Andy' })
set n.name = NULL
return n.name, n.age
-- 删除所有的属性
-- 使用一个空的map和等号, 这样即可删除节点所有属性
match (p { name: 'Peter' })
set p = { }
return p.name, p.age
------------------ 只能删除不带连接的节点 end ---------------
------------------ 删除节点连带着全部关系 start ---------------
-- 用 detach 删除
match(p:`期刊`{name: '西北地质'}) detach delete p
------------------ 删除节点连带着全部关系 start ---------------
5. Create relationships
--------------- 无结点,即创建节点的同时创建边关系 start --------------------
-- 创建两个节点node1和node2及type属性prop=value边关系
CREATE (node1)-[:type {prop: 'value'}]->(node2)
-- 三条语句一起执行
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
CREATE (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix)
-- 一条语句创建节点同时创建边
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'}),(Keanu:Person {name:'Keanu Reeves', born:1964}), (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix)
-- 创建两个节点多个关系
CREATE (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix), (Keanu)-[:ACTED_IN2 {roles:['Neo']}]->(TheMatrix)
-- 批量创建
create (a { name:"a" })-[:rel1]->(b {name :"b"}),(c {name:"c"})-[:rel2]->(d {name:"d"}),...
--------------- 无结点,即创建节点的同时创建边关系 end --------------------
--------------- 有结点,即对已存在的节点创建边关系 start --------------------
-- 创建 a -> b 的关系
# 语法1
MATCH(a:Person),(b:Person) WHERE a.id=2 AND b.id=3 CREATE(a)-[r:徒弟]->(b) RETURN r
MATCH(a:Power),(b:Person) WHERE a.name='人界' AND b.name='女娲' CREATE(a)-[r:所属]->(b) RETURN r
# 语法2
match (a:Student {name:"xiaoming"}), (b:Student {name:"zhangsan"})
create (a)-[r:同学]->(b) return a.name, type(r), b.name
# 将student属性class和Class的name相同的进行创建关系
match(n:`Student`),(m:`Class`)
with
n, m
where n.class = m.name
MERGE (n)-[s:`属于`]-(m)
return n,s,m;
-- 批量创建关系, 使用 UNWIND,数据为 List<Map<String. Object>>
UNWIND $props AS p match (n:文献{name: p.head}), (m:作者{name: p.tail}) create (n)-[:连接]->(m)
-- 说明: $props 为List<Map<String. Object>> 数组数据的变量参数,p为别名,p.head表示取map的head属性
--------------- 有结点,即对已存在的节点创建边关系 end --------------------
6. Delete edge relationship
-- 删除reba节点的关系`期刊`
match(p:Person{name: "reba"})-[r:`期刊`]->() delete r
-- 删除 作者-> 期刊 的边关系 连接
match(n:`作者`)-[r:`连接`]->(m:`期刊`) delete r
-- 删除所有 边关系"连接"
MATCH (n)-[rel:`连接`]->(r) delete rel
7. Query edge relationship
-- 查询所有边关系为"作者"的边
MATCH (n)-[rel:`作者`]->(r) return rel
--查询边关系为"作者"头结点 name为xx的数据
MATCH (n)-[rel:`作者`]->(r) where n.name='xx' return n, rel, r
8. db command
-- 所有可用的标签
call db.labels()
-- 所有的关系
call db.relationshipTypes()
9. Import
-- 如果需要导入其他文件系统文件,注释掉 dbms.directories.import=import
-- 是否允许从远程url load csv,默认不可以,如果允许远程url打开下面注释
dbms.security.allow_csv_import_from_file_urls=true
-- 导入csv,默认导入文件在neo4j安装目录import文件夹下
load csv with headers
from 'file:///tmdb_5000_movies.csv' as csv
create (
p:Movie{
title: csv.title,
url: csv.homepage,
year: toInteger(csv.year)
}
)
-- 无列名时可以使用列序号索引
load csv
from 'file:///tmdb_5000_movies.csv' as row
create (
p:Movie{
title: row[0],
url: row[1],
year: toInteger(row[2])
}
)
-- 导入关系
-- 无列名
load csv
from 'file:///tmdb_5000_movies.csv' as row
match(from:`Movie`{名称:row[0]}),(to:`Author`{名称:row[1]})
merge (from)-[r:作者]->(to)
--有列名
load csv with headers
from 'file:///tmdb_5000_movies.csv' as row
match(from:`Movie`{名称:row.from}),(to:`Author`{名称:row.to})
merge (from)-[r:作者]->(to)
10、OPTIONAL
If a relationship is optional, use OPTINAL MATCH. This is very similar to how outer joins work in SQL. Returns if the relationship exists, otherwise returns null where appropriate
-- 返回电影The Matrix这个节点的外向关系
MATCH (a:Movie { title: 'The Matrix' })
OPTIONAL MATCH (a)--(x)
RETURN x
-- 如果可选的元素为null,那么该元素的属性也返回null
-- 返回了x元素(查询中为null),它的name属性也为null
MATCH (a:Movie { title: 'The Matrix' })
OPTIONAL MATCH (a)-->(x)
RETURN x, x.name
-- 可选关系类型,可在查询中指定可选的关系类型
MATCH (a:Movie { title: 'The Matrix' })
OPTIONAL MATCH (a)<-[r: ACTED_IN]-()
RETURN r
11. Configuration
1、修改指定数据库
#默认
#dbms.default_database=neo4j
#修改
dbms.default_database=movies
2、修改可以从任意目录读取
#默认从import目录读取
dbms.directories.import=import
# 注释后可以从任意路径读取文件
#dbms.directories.import=import
3、修改是否允许从远程url load csv
# 默认不启用
#dbms.security.allow_csv_import_from_file_urls=true
# 开启后可以允许从远程url load csv
dbms.security.allow_csv_import_from_file_urls=true
4、允许其他电脑访问客户端
# 默认只允许 localhost 访问
#dbms.default_advertised_address=localhost
#允许其他客户端访问,启用配置
dbms.default_advertised_address=0.0.0.0
dbms.connector.bolt.listen_address=0.0.0.0:7687
dbms.connector.http.listen_address=0.0.0.0:7474
12. Apoc extension and use
-- 参考地址:https://www.yii666.com/blog/393843.html?action=onAll
-- 下载地址:https://neo4j.com/labs/apoc/4.4/installation/
-- 将对应的版本jar下载下来放入plugins文件夹中,重启服务
-- 使用命令 return apoc.version() 查询版本信息
-- 导出文件需要配置,在neo4j.conf 中添加
apoc.export.file.enabled=true
不配置,导出可能会报错
-- 导出json
CALL apoc.export.json.all("all.json",{useTypes:true})
-- 会将数据导出到安装包更目录下
-- 导出cypher
-- 参考地址:https://blog.csdn.net/GraphWay/article/details/109616926
-- 导出全部数据
call apoc.export.cypher.all("cypher_all.cypher", {cypherFormat:'updateAll'})
-- 使用查询语句导出
CALL apoc.export.cypher.query(
query,
file,
{configuration}
)
-- 示例:
CALL apoc.export.cypher.query(
"MATCH p=()-[rel:`包含`]->(),q=()-[rel2:`属于`]->() return p,q",
"cypher_pd.cypher",
{cypherFormat:'updateAll'}
)
1
Extended information
https://www.cnblogs.com/milton/archive/2022/05/02/16179836.html