Neo4j入门教程:添加、删除、修改和检查节点和关系,使用CQL和py2neo
Neo4j是图数据库中的佼佼者,用Java编写,社区版开源,商业版需要一笔费用。Neo4j是一个功能强大的NoSQL图数据库(Graph Database),它在网络上而不是在表中存储结构化数据。它是一个嵌入式、基于磁盘、完全事务性的 Java 持久性引擎,但将结构化数据存储在网络上(从数学角度称为图)而不是表中。Neo4j也可以被视为一个强大的图形引擎,具有成熟数据库的所有功能。Neo4j有一个非常酷的可视化界面,这是一般图数据库所不具备的。
本文通过一个简单的例子介绍了 Neo4j 的基本操作:添加、删除、修改、检查节点和边。我们想要实现的图(作为例子:简单易懂)如下: 示例
在上面的例子中,有两种类型的节点:城市和公司,以及一种类型的关系: (公司)- [属于]->(地点)。
CQL
Neo4j的CQL是一个非常重要的命令,类似于SQL语句。具体使用请参考:https://www.w3cschool.cn/neo4j/neo4j_cql_introduction.html。我们使用CQL来实现节点和关系的添加、删除、修改和查询。
ADD
城市节点可以通过以下命令使用:
create (city: City{name: "上海市", area: "6340.5平方千米", population: "2487.09万人", alias: ["沪", "申"]});
create (city: City{name: "北京市", area: "16410平方千米", population: "2189.31万人", alias: ["京", "帝都"]});
create (city: City{name: "深圳市", area: "1997.49平方千米", population: "1756万人", alias: ["深", "鹏城"]});
create (city: City{name: "杭州市", area: "16850平方千米", population: "1193万人", alias: ["杭"]});
上面的语句中,create表示新建,括号内为节点信息,节点类型(标签)为City,city为别名。大括号内是节点的属性。有四个属性:名称、面积、人口和别名。 注意:Neo4j 支持列表数据类型,但不支持时间和日期数据类型。
公司的节点可以通过以下命令来使用:
create (company: Company{name: "阿里"});
create (company: Company{name: "网易"});
create (company: Company{name: "百度"});
create (company: Company{name: "字节跳动"});
create (company: Company{name: "新浪"});
create (company: Company{name: "拼多多"});
create (company: Company{name: "B站"});
create (company: Company{name: "小红书"});
create (company: Company{name: "华为"});
create (company: Company{name: "腾讯"});
create (company: Company{name: "招商银行"});
创建关系的命令如下:
match (city: City{name: "杭州市"}), (company: Company{name: "阿里"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "杭州市"}), (company: Company{name: "网易"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "上海市"}), (company: Company{name: "拼多多"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "上海市"}), (company: Company{name: "B站"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "上海市"}), (company: Company{name: "小红书"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "北京市"}), (company: Company{name: "新浪"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "北京市"}), (company: Company{name: "百度"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "北京市"}), (company: Company{name: "字节跳动"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "深圳市"}), (company: Company{name: "华为"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "深圳市"}), (company: Company{name: "腾讯"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
match (city: City{name: "深圳市"}), (company: Company{name: "招商银行"}) create (company) -[r:belongTo{name: "所在城市"}]-> (city);
其实我们还可以使用以下命令来创建新的关系:
create (company: Company{name: "阿里"}) -[r:belongTo{name: "所在城市"}]-> (city:City{name: "杭州市"});
更新
如果需要更新 对于特定节点的属性,命令如下(例如,在上海节点缩写中添加名称“Modu”):
MATCH (city:City)
WHERE city.name="上海市"
SET city.alias=["沪", "申", "魔都"]
RETURN city;
上面的命令还包含查询(select),但只是CQL。查询类似于SQL,但又不一样。当然我们也可以调整一下关系。
删除
CQL的删除命令包括delete和delete。两者的区别在于:
- delete命令是删除节点,删除节点以及相关的节点和关系;
- 删除命令用于删除节点或关系。标签,从节点或关系中删除属性
我们以上海节点中删除别名属性为例。命令如下:
MATCH (city: City{name: "上海市"})
REMOVE city.alias
RETURN city;
注意,我们在删除节点时,需要保证该节点不与其他节点无任何关系地连接,即:该节点为孤立节点,否则报错。例如我们要删除上海节点,命令如下:
MATCH (city: City{name: "上海市"})
DELETE city;
错误如下: 删除上海节点会报错
select
CQL查询 - 指令为灵活而强大。我们只介绍几个简单的命令。
- 所有节点查询:
match (n) return (n);
- 所有节点计数查询
match (n) return count(n);
- 所有业务节点查询
match (n:Company) return (n);
- 北京城市节点查询
match (n:City{name: "北京市"}) return (n);
- 招商银行与深圳关系查询
match (a:Company{name: "招商银行"}) -[r]-> (b:City{name: "深圳市"}) return type(r);
- 该地图上杭州市下的查询公司
match (a:Company) -[r:belongTo]-> (b:City{name: "杭州市"}) return (a);
CQL还支持更高级的查询,例如最短路径查询等。
py2neo
py2neo是一个用于与Neo4j通信的Python库。官方文档地址为http://py2neo.org/v3/index.html,
GitHub地址为https://github.com/technige/py2neo。
下面讲解如何使用py2neo对Neo4j进行简单的操作。
neo4j 连接
py2neo 与 Neo4j 的连接需要 Neo4j 服务 URL、用户名和密码。示例连接的Python代码如下:
# -*- coding: utf-8 -*-
from py2neo import Graph
url = "http://localhost:7474"
username = "neo4j"
password = "password"
graph = Graph(url, auth=(username, password))
print("neo4j info: {}".format(str(graph)))
输出结果如下:
neo4j info: Graph('http://neo4j@localhost:7474')
ADD
我们创建4个城市节点和11个业务节点。代码如下:
from py2neo import Node, Relationship, Subgraph
city_list = [{"name": "上海市", "area": "6340.5平方千米", "population": "2487.09万人", "alias": ["沪", "申"]},
{"name": "北京市", "area": "16410平方千米", "population": "2189.31万人", "alias": ["京", "帝都"]},
{"name": "深圳市", "area": "1997.49平方千米", "population": "1756万人", "alias": ["深", "鹏城"]},
{"name": "杭州市", "area": "16850平方千米", "population": "1193万人", "alias": ["杭"]}]
company_list = [{"name": "阿里"},
{"name": "网易"},
{"name": "百度"},
{"name": "新浪"},
{"name": "字节跳动"},
{"name": "小红书"},
{"name": "B站"},
{"name": "拼多多"},
{"name": "华为"},
{"name": "招商银行"},
{"name": "腾讯"}
]
for city in city_list:
node = Node("City", **city)
graph.create(node)
for company in company_list:
node = Node("Company", **company)
graph.create(node)
或者也可以通过子图来创建,效率更高。使用子图的示例代码如下:
from py2neo import Node, Relationship, Subgraph
city_list = [{"name": "上海市", "area": "6340.5平方千米", "population": "2487.09万人", "alias": ["沪", "申"]},
{"name": "北京市", "area": "16410平方千米", "population": "2189.31万人", "alias": ["京", "帝都"]},
{"name": "深圳市", "area": "1997.49平方千米", "population": "1756万人", "alias": ["深", "鹏城"]},
{"name": "杭州市", "area": "16850平方千米", "population": "1193万人", "alias": ["杭"]}]
company_list = [{"name": "阿里"},
{"name": "网易"},
{"name": "百度"},
{"name": "新浪"},
{"name": "字节跳动"},
{"name": "小红书"},
{"name": "B站"},
{"name": "拼多多"},
{"name": "华为"},
{"name": "招商银行"},
{"name": "腾讯"}
]
node_list = []
for city in city_list:
node_list.append(Node("City", **city))
for company in company_list:
node_list.append(Node("Company", **company))
new_sub = Subgraph(node_list)
graph.create(new_sub)
创建City节点和Business节点之间的关系 示例代码如下:
# 创建关系
from py2neo import NodeMatcher
rel_dict = {"上海市": ["小红书", "B站", "拼多多"],
"北京市": ["百度", "新浪", "字节跳动"],
"深圳市": ["华为", "招商银行", "腾讯"],
"杭州市": ["阿里", "网易"]}
node_matcher = NodeMatcher(graph=graph)
for key, vals in rel_dict.items():
for val in vals:
start_node = node_matcher.match("Company", name=val).first()
end_end = node_matcher.match("City", name=key).first()
rel = Relationship(start_node, "belongTo", end_end, name="所在城市")
graph.create(rel)
这样创建的图是开始演示的示例。当然,我们也可以使用Subgraph来创建,这样会更加高效。
UPDATE
如果需要更新节点属性,Python代码示例如下(例如上海节点缩写添加“Modu”):
# before update
node_matcher = NodeMatcher(graph=graph)
node = node_matcher.match("City", name="上海市").first()
print(node.__repr__())
# update node
node["alias"] = ['沪', '申', '魔都']
graph.push(node)
# after update
node = node_matcher.match("City", name="上海市").first()
print(node.__repr__())
输出结果为如下:
Node('City', alias=['沪', '申'], area='6340.5平方千米', name='上海市', population='2487.09万人')
Node('City', alias=['沪', '申', '魔都'], area='6340.5平方千米', name='上海市', population='2487.09万人')
当然我们也可以更新关系。
DELETE
以删除上海节点的别名属性为例。 Python代码示例如下:
# before delete
node_matcher = NodeMatcher(graph=graph)
node = node_matcher.match("City", name="上海市").first()
print(node.__repr__())
# delete node property
del node["alias"]
graph.push(node)
# after update
node = node_matcher.match("City", name="上海市").first()
print(node.__repr__())
输出结果如下:
Node('City', alias=['沪', '申', '魔都'], area='6340.5平方千米', name='上海市', population='2487.09万人')
Node('City', area='6340.5平方千米', name='上海市', population='2487.09万人')
当然,我们也可以删除节点。
SELECT
py2neo 也可以很好地支持查询语句。示例代码如下:
- 所有节点查询:
graph.nodes.match().all()
- 所有节点计数查询
len(graph.nodes.match().all())
- 所有业务节点查询
graph.nodes.match("Company").all()
- 名称查询 对于北京城市节点
graph.nodes.match("City", name="北京市").all()
- ,查询招商银行与深圳的关系
node_matcher = NodeMatcher(graph=graph)
end_node = node_matcher.match("City", name="深圳市").first()
start_node = node_matcher.match("Company", name="招商银行").first()
print(graph.match([start_node, end_node]).first())
- 询问地图上杭州下的公司
from py2neo import RelationshipMatcher
node_matcher = NodeMatcher(graph=graph)
node = node_matcher.match("City", name="杭州市").first()
rel_matcher = RelationshipMatcher(graph=graph)
find_rels = rel_matcher.match([None, node], r_type="belongTo").all()
print([_.start_node for _ in find_rels if _.start_node.has_label("Company")])
py2neo也支持CQL语句。我们以最后一条查询语句为例。示例代码如下:
cql = 'match (a:Company) -[r:belongTo]-> (b:City{name: "杭州市"}) return (a); '
print(graph.run(cql).data())
输出结果如下:
[{'a': Node('Company', name='网易')}, {'a': Node('Company', name='阿里')}]
总结
综上所述,我们可以了解到neo4j的CQL和py2neo各有千秋。 CQL在某些查询情况下比较有用,而py2neo可以帮助我们使用Python。对Neo4j实施某些操作也非常方便。
本文简单介绍了添加、删除、修改、查询Neo4j节点和关系,以及使用CQL和py2neo。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。