使用 Docker Desktop 安装 Neo4j 知识图谱

一、简介

Neo4j是一个高性能的,基于java开发的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中;它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎。

Neo4j分为企业版和社区版,企业版可以创建多个数据库,链接多个数据库,但是收费......;社区版只能链接一个数据库,所以社区版不支持创建数据库命令。

Neo4j部署后默认创建名字为 neo4j 的数据库,可以直接链接这个数据库。

二、使用 Docker 安装 Neo4j

官网文档:https://neo4j.com/docs/

官网下载地址:https://neo4j.com/download-center

国内镜像地址(所有版本都有):https://we-yun.com/doc/neo4j/

1、安装 Docker Desktop

请看这里:Docker Desktop 安装使用教程

2、使用 Docker Desktop 安装 Neo4j 镜像

powershell 复制代码
# 拉取 Neo4j 镜像
docker pull neo4j:5.26.2
powershell 复制代码
# 启动 并 设置 neo4j 挂载
docker run -it -d -p 7474:7474 -p 7687:7687 -v /home/neo4j/data:/data -v /home/neo4j/logs:/logs -v /home/neo4j/conf:/var/lib/neo4j/conf -v /home/neo4j/import:/var/lib/neo4j/import -v /home/neo4j/plugins:/var/lib/neo4j/plugins -e NEO4J_AUTH=neo4j/password --name neo4j neo4j:5.26.2


3、访问界面

访问地址:http://localhost:7474/browser/

4、Cypher 和 使用 Neo4J

在这里有的小伙伴就会想我不太会使用Docker 能不能安装其他版本的呀?当然这个也是有的,小编之前也有写过一篇关于本地安装和怎么使用Neo4J的详细文章,大家有需要可以通过下面链接进行学习。

请看这里:Noe4J 超级详细的安装与使用

4.1、输入 CQL语句

没错,就是在大家最喜欢的美元符号那里输入 CQL语句的。这里我们拿学生和老师举例来说明。

4.2、增加节点

Neo4j使用的是create 命令进行增加,就类似与MySQL中的insert。

语法如下:
create (node-name:label-name)
create (node-name:label-name { property1-name:property1-Value, ..., property3-name:property3-Value})

  • node - name:它是我们要创建的节点名称
  • label - name:它是我们要创建的标签名称
  • property1 - name:就是属性名称
  • property1 - Value:就是属性值
1. 创建一个学生节点(只有节点,没有属性):
sql 复制代码
create (s:Student)

在美元符号输入完上面的CQL后,回车 或者 点击右侧的三角号执行按钮,会看到如下结果:

2.创建一个学生节点(创建具有属性的节点)

创建一个id为10000,名字为张三,年龄为18岁,性别为男的学生节点

sql 复制代码
create (s:Student{id:10000, name:"张三",age:18,sex:1}) 

执行后,会看到如下的结果:

4.3、查询

我们在上一步创建了没有属性的节点和有属性的节点,那么问题来了,我们怎么查看呢?查询咯~

Neo4j使用的是match ... return ... 命令进行查询,就类似与MySQL中的select。

我们查询刚刚创建的节点信息。

1.全部查询学生
sql 复制代码
match (s:Student) return s

从上图可以看到我们刚刚创建的两个节点,一个是没有属性节点,一个是有属性的节点。两个节点是以图的形式展示,我们也可以切换左边的Graph(图)、Table(表格)、Text(文本)等来以不同的形式展示。

2.查询全部或者部分字段

只需要把要展示的字段以节点名 + 点号 + 属性字段 拼接即可,如下:

sql 复制代码
match (s:Student) return s.id,s.name,s.age,s.sex

这样就清楚的看到我们插入的学生属性信息。因为有一个是没有属性的节点,所以表格中第2行显示的各个值都是null。

3.查询满足年龄age等于18的学生信息
sql 复制代码
match (s:Student) where s.age=18 return s.id,s.name,s.age,s.sex

怎么样,这条件查询 是不是和MySQL的很相似。当然还有排序、分组、联合、分页等。为了能更好的演示这几种,我们先插入一部分数据,逐条插入:

sql 复制代码
create (s:Student{id:10001, name:"李四",age:18,sex:1}) return screate (s:Student{id:10002, name:"王五",age:19,sex:1}) return screate (s:Student{id:10003, name:"赵六",age:20,sex:1}) return screate (s:Student{id:10004, name:"周七",age:17,sex:0}) return screate (s:Student{id:10005, name:"孙八",age:23,sex:1}) return screate (s:Student{id:10006, name:"吴九",age:15,sex:1}) return screate (s:Student{id:10007, name:"郑十",age:19,sex:0}) return screate (s:Student{id:10008, name:"徐十一",age:18,sex:1}) return screate (s:Student{id:10009, name:"朱十二",age:21,sex:1}) return screate (s:Student{id:10010, name:"谭十三",age:22,sex:1}) return s

这个我们在create 的语句后面加上了return,意思就是我插入完你要把数据返回给我看下,如下:

这样,我们的数据就造好了,我们可以先查询全部的看下:

sql 复制代码
match (s:Student) return s.id,s.name,s.age,s.sex

图中的左下角我们可以看到一共有12条数据。一条没有属性的 + 11条有属性的。

4.查询出所有的男生(sex=1)并按年龄倒叙排序
sql 复制代码
match (s:Student) where s.sex=1 return s.id,s.name,s.age,s.sex order by s.age desc

很清晰,是以age倒叙排序的。

5.查询出名字不为null,且按性别分组

这里要注意一点,CQL中的分组和SQL是有所差异的,在CQL中不用显式的写group by分组字段,由解释器自动决定:即未加聚合函数的字段自动决定为分组字段。

sql 复制代码
match (s:Student) where s.name is not null return s.sex,count(*)

不难看出,上面是按sex字段分组的。

6.union联合查询(查询性别为男或者女的,且年龄为19岁的学生)

有union,当然也有 union all,这两个的区别和SQL中也是一样的。

  • union:对两个结果集进行并集操作,不包括重复行;
  • union all:对两个结果集进行并集操作,包括重复行;
sql 复制代码
match (s:Student) where s.sex=1 and s.age=19 return s.id,s.name,s.sex,s.ageunion match (s:Student) where s.sex=0 and s.age=19 return s.id,s.name,s.sex,s.age
7.分页查询(每页4条,查询第3页的数据)
sql 复制代码
match (s:Student) return s.id,s.name,s.sex,s.age skip 8 limit 4

CQL中的skip表示跳过多少条,limit表示获取多少条。每页4条,查询第三页的数据,也就是跳过前8条,查询4条,或者说从第8条开始,不包括第8条,然后再查询4条。

8.in操作(查询id为10001和10005的两个数据)
sql 复制代码
match (s:Student) where s.id in [10001,10005] return s.id,s.name,s.sex,s.age

这里 用的是中括号,和SQL中是有区别的。

4.4、增加关系

创建关系的语法如下:
match (node1-label-name:node1-name),(node2-label-name:node2-name) where condition create (node1-label-name)-[relationship-label-name:relationship-name] ->(node2-label-name)
match (node1-label-name:node1-name),(node2-label-name:node2-name) where condition create (node1-label-name)-[relationship-label-name:relationship-name {relationship-properties}]->(node2-label-name)

  • node1-name 表示节点名称,label1-name表示标签名称
  • relationship - name 表示关系节点名称,relationship-label-name表示关系标签名称
  • node2 - name 表示节点名称,label2-name表示标签名称

上面我们介绍了增加单个节点和查询的知识点。这里我们介绍下增加关系。为了存在关系,我们先创建一个老师节点。

创建一个教语文的年龄为35岁的男的王老师:

sql 复制代码
create (t:Teacher{id:20001,name:"王老师",age:35,sex:1,teach:"语文"}) return t
1.假设王老师所教的班级有3个学生:张三、李四、王五,这里我们就要创建王老师 和 3个学生的关系,注意,这里是为两个现有节点创建关系。
sql 复制代码
match (t:Teacher),(s:Student) where t.id=20001 and s.id=10000 create (t)-[teach:Teach]->(s)return t,teach,s

这样,王老师和张三的关系就创建了。下面,我们再继续创建王老师 和 李四、王五的关系。

sql 复制代码
match (t:Teacher),(s:Student) where t.id=20001 and s.id=10001 create (t)-[teach:Teach]->(s)return t,teach,s
match (t:Teacher),(s:Student) where t.id=20001 and s.id=10002 create (t)-[teach:Teach]->(s)return t,teach,s

老师和学生的关系增加了,我们查询下:

sql 复制代码
match (t:Teacher)-[teach:Teach]-(s:Student) return t,teach,s

这关系就很显然了吧。王老师教张三、李四、王五。

2.我们给广东和深圳创建关系,深圳是属于广东省的。但是并没有广东省份节点和深圳市节点,没错,我们就是为两个不存在的节点创建关系。
sql 复制代码
create (c:City{id:30000,name:"深圳市"})-[belongto:BelongTo{type:"属于"}]->(p:Province{id:40000,name:"广东省"})

我们查询下我们创建的深圳和广东的关系。

sql 复制代码
match (c:City{id:30000,name:"深圳市"})-[belongto:BelongTo{type:"属于"}]->(p:Province{id:40000,name:"广东省"}) return c,belongto,p

当然,属性都非必填的,只是为了更加准确。

如果我们要查询Neo4j中全部的关系需要怎么写CQL呢,如下:

sql 复制代码
match (a)-[b]-(c) return a,b,c

4.5、修改

Neo4j中的修改也和SQL中的是很相似的,都是用set子句。和es一样,Neo4j CQL set子句也可以向现有节点或关系添加新属性。

通过上面的查询,我们已经熟记了学生张三的年龄是18岁,2020年了,张三也长大了一岁,所以我们就需要把张三的年龄改为19。

sql 复制代码
match (s:Student) where s.name="张三" set s.age=19 return s

从图中的红色框中我们可以清晰的看到张三的年龄已经更新到19了:

4.6、删除

Neo4j中的删除也和SQL中的是很相似的,都是delete,当然,除了delete删除,还有remove删除。

1.删除单个节点

这里以删除学生节点中没有属性的来举例:

先查询下学生中没有属性的节点

sql 复制代码
match (s:Student) where s.name is null return s

然后我们再删除这个节点:

sql 复制代码
match (s:Student) where s.name is null delete s

把上面查询的CQL中的return 改为 delete 就OK了。

执行完上面的删除CQL后,我们再重新查询下:

发现已经不存在没有属性的学生节点了,这说明我们已经删除成功了。

2.删除带关系的节点

这里我们以删除广东和深圳的关系来举例:

sql 复制代码
match (c:City{id:30000,name:"深圳市"})-[belongto]->(p:Province{id:40000,name:"广东省"}) return c,belongto,p

这个时候是有数据的。

然后我们执行下面的删除CQL,把上面的查询CQL中的return 改为 delete哦:

sql 复制代码
match (c:City{id:30000,name:"深圳市"})-[belongto]->(p:Province{id:40000,name:"广东省"}) delete c,belongto,p

执行完上面的删除CQL后我,我们重新再查询下:

发现已经不存在广东和深圳这两个节点以及关系了。

3.删除全部节点已经关系

这里这个CQL主要用作测试的,生产环境可不要执行,否则,真的是从删库到跑路了~

sql 复制代码
match (n) detach delete n
4.删除节点或关系的现有属性

可以通过remove来删除节点或关系的现有属性。

例如,我们删除学生李四节点中的sex属性:

sql 复制代码
match (s:Student{id:10001}) remove s.sex

执行完上面的remove CQL后,我们重新查询下:

看到李四的sex属性为null了。

5、将 CSV 数据导入 Neo4j

官网文档: https://neo4j.com/docs/getting-started/data-import/csv-import/

LOAD CSV可以处理本地和远程文件,并且每个文件都有一些关联的语法。 这可能是一件很容易错过的事情,并最终导致访问错误,因此此处对规则进行了说明。

出于安全原因,默认情况下,本地文件只能从 Neo4j 导入目录读取,该目录因作系统而异。 每个作系统的文件位置都列在我们的 Neo4j作手册 → 文件位置 中。 建议将文件放在 Neo4j 的 import 目录中,因为它可以保证环境安全。 但是,如果您需要访问其他位置的文件,您可以在我们的 Cypher 手册 → LOAD CSV 介绍中找到要更改的设置。

sql 复制代码
例子
//Example 1 - file directly placed in import directory (import/data.csv)
LOAD CSV FROM "file:///data.csv"

//Example 2 - file placed in subdirectory within import directory (import/northwind/customers.csv)
LOAD CSV FROM "file:///northwind/customers.csv"

Web 托管文件可以直接使用其 URL 进行引用,例如 . 但是,必须设置权限,以便外部源可以读取文件。 要从本地文件系统读取文件,您需要检查配置设置是否设置为 。 有关与联机文件导入相关的访问的更多信息,请参阅此知识库文章。 但请记住,在 Neo4j v5 中,配置设置已重命名,并已更改为https://host/path/data.csvdbms.security.allow_csv_import_from_file_urlstruedbms.directories.importserver.directories.import

sql 复制代码
例子
//Example 1 - website
LOAD CSV FROM 'https://data.neo4j.com/northwind/customers.csv'

//Example 2 - Google
LOAD CSV WITH HEADERS FROM 'https://docs.google.com/spreadsheets/d/<yourFilePath>/export?format=csv'

6、使用 Python 导入 Neo4j

由于 使用 LOAD CSV 命令比较麻烦,并且在实际的工作中,都不会这样去操作,而是使用代码连接数据库进行开发。我这里使用了Python 连接Neo4j 进行数据库操作。

根据这些信息,以下是修正后的代码,确保使用Bolt协议和正确的端口:

Python脚本尝试通过Bolt协议连接到Neo4j数据库,但是连接失败,并且错误提示中提到"looks like HTTP"。这通常意味着以下几个问题之一:

  • 1、端口错误:你使用的端口可能是HTTP端口(7474),而Bolt协议通常使用的是7687端口。确保你使用的是正确的Bolt端口。
  • 2、协议错误:如果你确实想要使用Bolt协议,确保URI以bolt://开头,而不是http://。
  • 3、网络问题:网络配置可能阻止了连接,例如防火墙设置或网络策略。
  • 4、Neo4j配置:Neo4j服务器可能没有配置为监听Bolt端口。
1.使用Bolt协议查询Neo4j

通过这种方式可以查询出上面我们在Neo4j 直接查询得出来的结果,只是这种会输出到控制台,这里只是一个小案例,大家可以通过实际需求进行修改

python 复制代码
from neo4j import GraphDatabase

# 连接信息
uri = "bolt://xx.xx.xx.xxx:7687"  # Neo4j 连接地址,使用Bolt协议
username = "neo4j"              # 用户名
password = "password"            # 数据库密码

# 创建驱动实例
driver = GraphDatabase.driver(uri, auth=(username, password))

# 定义一个函数来执行查询
def get_students(driver):
    with driver.session() as session:
        # Cypher查询
        query = "MATCH (s:Student) RETURN s.id, s.name, s.age, s.sex"
        # 执行查询并获取结果
        results = session.run(query)
        # 打印结果
        for record in results:
            print(record["s.id"], record["s.name"], record["s.age"], record["s.sex"])

# 调用函数执行查询
get_students(driver)

# 关闭连接
driver.close()
2.使用Bolt协议 导入数据到 Neo4j,并创建关系

通过这种方式可以连接到 Neo4j ,任何创建并批量导入CSV的数据,这种方式比起LOAD CSV 命令简单很多,同时还可以在代码中对数据进行一些复杂处理后在导入,不用我们手动处理。

python 复制代码
import csv
from neo4j import GraphDatabase

# 连接信息
uri = "bolt://xx.xx.xx.xxx:7687"  # Neo4j 连接地址,使用Bolt协议
username = "neo4j"              # 用户名
password = "password"            # 数据库密码

# 创建驱动实例
driver = GraphDatabase.driver(uri, auth=(username, password))

# 定义一个函数来执行查询
def create_artists_and_relationships(driver, csv_file_path):
    with driver.session() as session:
        # 读取CSV文件
        with open(csv_file_path, mode='r', encoding='utf-8') as file:
            reader = csv.DictReader(file)
            for row in reader:
                # 构建Cypher语句创建Artists节点
                create_artist_query = (
                    "CREATE (a:Artists {ID: $ID, Name:$Name, Genre: $Genre}) "
                    "RETURN a"
                )
                #ID, Name, Genre
                artist_params = {
                    "ID": int(row['ID']),
                    "Name": row['Name'],
                    "Genre": row['Genre']
                }
                # 执行创建Artists节点的Cypher语句
                artist_node = session.run(create_artist_query, **artist_params).single()[0]

                # 如果CSV中有指定父级列,创建关系
                if 'Parent' in row and row['Parent']:
                    parent_ids = row['Parent'].split(',')  # 假设父级ID以逗号分隔
                    for parent_id in parent_ids:
                        if parent_id:  # 确保parent_id不是空字符串
                            # 构建Cypher语句创建关系
                            create_relationship_query = (
                                "MATCH (a:Artists {ID: $artist_id}), (p:Artists {ID:$parent_id}) "
                                "CREATE (a)-[:CHILD_OF]->(p)"
                            )
                            relationship_params = {
                                "artist_id": artist_params['ID'],
                                "parent_id": int(parent_id)
                            }
                            # 执行创建关系的Cypher语句
                            session.run(create_relationship_query, **relationship_params)

# 调用函数执行查询
csv_file_path = r'C:\Downloads\artists.csv'  # 替换为你的CSV文件路径
create_artists_and_relationships(driver, csv_file_path)

# 关闭连接
driver.close()

到这里整篇关于Docker 安装 Neo4j ,以及怎么用使用 Neo4j 还有用 Python 怎么连接并操作Neo4j 就讲完了。

相关推荐
REDcker6 分钟前
Android 15 16KB 内存页适配详解
android·开发语言·python
爱吃苹果的梨叔8 分钟前
KVM和分布式坐席参数怎么看?端口、通道、节点都是什么意思
python
量化吞吐机14 分钟前
近期AI量化开发,先跑最小流程再谈复杂功能
人工智能·python
杰佛史彦明120 分钟前
PDF 表格转 CSV:Python 实现方法与代码解析
开发语言·python·pdf
XUHUOJUN25 分钟前
Windows Server 2025 RAC vs Stretch Cluster 技术定位
windows·microsoft·azure local
智写-AI29 分钟前
推荐一下好用的降英文AI工具工具
人工智能·python
迷枫71239 分钟前
简单sql与dm功能实验记录
数据库·sql·oracle
承渊政道1 小时前
OneNav书签导航实操:极空间Docker部署、分类整理与公网访问
运维·docker·内网穿透·cpolar·nas·onenav·轻量级部署
江华森1 小时前
Python神经网络编程(四):Python从零搭建神经网络
开发语言·python·神经网络
zhanghaofaowhrql1 小时前
Spring Data JPA Repository 详解:从基础到高级用法
java·数据库·sql