Neo4j入门(一)节点、关系的增删改查

本文作为笔者入门Neo4j的第一篇文章,后续将会更多地介绍Neo4j及知识图谱相关的内容。

Neo4j入门(一)节点、关系的增删改查
Neo4j是图数据库中的佼佼者,采用Java编写,社区版已开源,商业版需收费。Neo4j是一个高性能的NoSQL图形数据库(Graph Database),它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。Neo4j拥有十分酷炫的可视化界面,这是一般图数据库所不具备的。
本文将通过一个简单的例子来介绍Neo4j中的基本操作:对节点和边实现增删改查。我们想要实现的图(作为例子,简单易懂)如下:

Neo4j入门(一)节点、关系的增删改查
在上述例子中,共有两类节点:City和Company,一类关系:(Company) -[belongTo]-> (City)。

; CQL

Neo4j 的 CQL 是非常重要的命令,类似于 SQL 语句,具体的用法可以参考:https://www.w3cschool.cn/neo4j/neo4j_cql_introduction.html。我们使用CQL实现节点、关系的增删改查。

ADD

City的节点可以通过使用如下命令使用:

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表示新建,小括号内是节点信息,节点的类型(label)是City
,city是其别名,花括号内是该节点的属性,共有name、area、population、alias四个属性。 注意:Neo4j支持列表这个数据类型,但不支持时间日期这个数据类型。
Company的节点可以通过使用如下命令使用:

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: "杭州市"});

update

如果需要更新某个节点的属性,命令如下(比如将上海市节点的简称新增”魔都”这个名字):

MATCH (city:City)
WHERE city.name="上海市"
SET city.alias=["沪", "申", "魔都"]
RETURN city;

Neo4j入门(一)节点、关系的增删改查
上述命令也涉及到了查询(select),只是CQL的查询与SQL接近但又不相同。当然,我们也可以修改某条关系。

delete

CQL的删除命令有delete和remove,两者的区别为:

  • delete命令为删除节点、删除节点及相关节点和关系;
  • remove命令为删除节点或关系的标签、删除节点或关系的属性

我们以删除上海市节点的alias属性为例,命令如下:

MATCH (city: City{name: "上海市"})
REMOVE city.alias
RETURN city;

Neo4j入门(一)节点、关系的增删改查
注意,当我们在删除某个节点的时候,需要确定该节点无其他节点无关系相连,即该节点为孤立节点,否则,就会报错。比如,我们想删除上海市这个节点,命令如下:
MATCH (city: City{name: "上海市"})
DELETE city;

报错如下:

Neo4j入门(一)节点、关系的增删改查

select

CQL的查询语句是灵活、功能强大的。我们仅介绍简单的几个命令。

  • 查询所有的节点:
match (n) return (n);
  • 查询所有节点的数量
match (n) return count(n);
  • 查询所有的Company节点
match (n:Company) return (n);
  • 查询名字为北京市的City节点
match (n:City{name: "北京市"}) return (n);
  • 查询招商银行与深圳市的关系
match (a:Company{name: "招商银行"}) -[r]-> (b:City{name: "深圳市"}) return type(r);
  • 查询该图谱中杭州市下面的Company
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的服务网址,用户名和密码,示例连接Python代码如下:


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个City节点和11个Company节点,代码如下:

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)

或者可以通过子图(Subgraph)来创建,这样创建效率更高,使用子图的示例代码如下:

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节点与Company节点之间的关系的示例代码如下:


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代码如下(比如将上海市节点的简称新增”魔都”这个名字):


node_matcher = NodeMatcher(graph=graph)
node = node_matcher.match("City", name="上海市").first()
print(node.__repr__())

node["alias"] = ['沪', '申', '魔都']
graph.push(node)

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

我们以删除上海市节点的alias属性为例,示例Python代码如下:


node_matcher = NodeMatcher(graph=graph)
node = node_matcher.match("City", name="上海市").first()
print(node.__repr__())

del node["alias"]
graph.push(node)

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())
  • 查询所有的Company节点
graph.nodes.match("Company").all()
  • 查询名字为北京市的City节点
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())
  • 查询该图谱中杭州市下面的Company
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的使用方法。后续会持续更新Neo4j相关内容,欢迎大家关注~
2021.7.13-7.14深夜,最近上海酷暑~

Original: https://blog.csdn.net/jclian91/article/details/118685492
Author: 山阴少年
Title: Neo4j入门(一)节点、关系的增删改查

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/595154/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球