Hi,大家好,我是半亩花海。本文主要介绍如何使用 Neo4j 图数据库呈现语义网络,并通过 Python 将语义网络的数据写入数据库。具体步骤包括识别知识中的节点和关系,将其转化为图数据库的节点和边,最后通过代码实现数据的写入和展示。
目录
一、实验目的
(1)了解向数据库中写入语义网络的方法。
(2)简单使用Neo4j呈现语义网络。
二、实验要求
本次实验后,能理解语义网络的节点(Node)和关系(Relationship)在数据库中是如何呈现的。
三、实验原理
按照5.3节《知识的语义网络表示》介绍的方法(5.3.1-事实性知识的表示,5.3.2-情况、动作和事件的表示,5.3.3-连词和量词的表示,5.3.4-用语义网络表示知识的步骤),将一个事实用语义网络表示,首先要找出它的节点,再描述它与其他节点的关系,最后用 Python 写入数据库中。
四、实验步骤
1. 环境配置
(1)下载 JDK
官网下载链接:Java Downloads | Oracle
JDK版本的选择一定要恰当,这里我下载安装的是jdk11。Jdk的版本很重要,需要与neo4j匹配适应,版本太低或太高都可能导致后续的neo4j无法使用。
可以参考CSDN上的经验贴,比如借鉴以下这个博主的经验:Neo4j安装教程及版本匹配_neo4j5.15对应哪个版本jdk-CSDN博客(Neo4j安装教程及版本匹配_neo4j5.15对应哪个版本jdk-CSDN博客)。
(2)安装 neo4j
安装好JDK之后,便可以安装neo4j。
官方下载链接:Neo4j Deployment Center - Graph Database & Analytics
根据上述jdk对应版本来看,这里我下载安装的是neo4j 4.4.33。
(3)配置环境变量
安装好 JDK 和 neo4j 之后就要开始配置环境变量。步骤如下:右键单击此电脑→属性→高级系统设置→高级→环境变量,着眼于在下方的系统变量区域。
- 新建第一个环境变量,变量名为JAVA_HOME,变量值是jdk的文件路径,这里我是E:\jdk\jdk-11.0.23_windows-x64_bin\jdk-11.0.23。
- 新建第二个环境变量,变量名为NEO4J_HOME,变量值是neo4j的文件路径,这里我是E:\neo4j\neo4j-community-4.4.33-windows\neo4j-community-4.4.33。
- 编辑Path→新建→输入 %JAVA_HOME%\bin 和 %NEO4J_HOME%\bin
(4)启动 neo4j
以管理员身份运行 cmd。在命令行处输入neo4j.bat console。
如出现此界面,则证明neo4j启动成功。在浏览器中输入上述界面中给出的网址http://localhost:7474/,则会显示如下界面。
默认的用户名和密码均为neo4j。但是可以修改密码,记住这个密码,后续代码会用到。随后cmd也会出现上述结果。至此,neo4j安装完毕。
2. 安装 py2neo 库
在cmd中输入以下命令即可:pip install py2neo。
3. 从 py2neo 包导入库
from py2neo import Graph, Node, Relationship
4. 连接 Neo4j 图形数据库
# 连接Neo4j图形数据库
g = Graph('http://localhost:7474', user='neo4j', password='0123456789', name='neo4j')
此处,密码我修改为0123456789,进入neo4j。
5. 创建并覆盖节点
植物、树、草、叶、根、水草、水、果树、结果、梨树、结梨这些节点类继承自StructuredNode类,包括节点属性和连接关系。
即将要构造的事实为“树和草都是植物。树和草都有叶和根。水草是草,且生长水中。果树是树,且会结果。梨树是果树的一种,它会结梨”。
# 删除数据库中的所有节点和关系
g.delete_all()
# 创建节点
test_node_1 = Node("植物", name="植物")
test_node_2 = Node("根", name="根")
test_node_3 = Node("叶", name="叶")
test_node_4 = Node("草", name="草")
test_node_5 = Node("水草", name="水草")
test_node_6 = Node("水中", name="水中")
test_node_7 = Node("树", name="树")
test_node_8 = Node("果树", name="果树")
test_node_9 = Node("结果", name="结果")
test_node_10 = Node("梨树", name="梨树")
test_node_11 = Node("结梨", name="结梨")
# 覆盖创建节点
g.merge(test_node_1, "植物", "name")
g.merge(test_node_2, "根", "name")
g.merge(test_node_3, "叶", "name")
g.merge(test_node_4, "草", "name")
g.merge(test_node_5, "水草", "name")
g.merge(test_node_6, "水中", "name")
g.merge(test_node_7, "树", "name")
g.merge(test_node_8, "果树", "name")
g.merge(test_node_9, "结果", "name")
g.merge(test_node_10, "梨树", "name")
g.merge(test_node_11, "结梨", "name")
6. 创建关系
# 创建关系
relation1 = Relationship(test_node_1, 'Have', test_node_2)
relation2 = Relationship(test_node_1, 'Have', test_node_3)
relation3 = Relationship(test_node_4, 'AKO', test_node_1)
relation4 = Relationship(test_node_5, 'AKO', test_node_4)
relation5 = Relationship(test_node_5, 'Live', test_node_6)
relation6 = Relationship(test_node_7, 'AKO', test_node_1)
relation7 = Relationship(test_node_8, 'AKO', test_node_7)
relation8 = Relationship(test_node_8, 'Can', test_node_9)
relation9 = Relationship(test_node_10, 'ISA', test_node_8)
relation10 = Relationship(test_node_11, 'Can', test_node_10)
7. 将关系应用到图中
# 将关系应用到图中
g.merge(relation1)
g.merge(relation2)
g.merge(relation3)
g.merge(relation4)
g.merge(relation5)
g.merge(relation6)
g.merge(relation7)
g.merge(relation8)
g.merge(relation9)
g.merge(relation10)
五、实验结果
六、实验小结
- jdk和neo4j的版本需要匹配,这里我用的是 jdk11和neo4j 4.4.33,其中任何一个版本过高或过低都会导致安装库之后运行错误。
- 配置环境变量的时候,需要注意两个变量命名和路径的正确性。
- 创建节点和关系的时候需要反复注意各变量之间逻辑关系。
七、完整代码
# 从neomodel包导入类从neomodel包导入类
from neomodel import StructuredNode, StringProperty, RelationshipTo, RelationshipFrom, config
# 连接Neo4j图形数据库
config.DATABASE_URL = 'bolt://meo4j:neo4j@localhost:7687'
# 编写节点类
# 植物、树、草、叶、根、水草、水、果树、结果、梨树、结梨这些节点类继承自StructuredNode类,包括节点属性和连接关系。
class Plant(StructuredNode):
name = StringProperty(unique_index=True)
has1 = RelationshipFrom('Tree', 'AKO')
has2 = RelationshipFrom('Grass', 'AKO')
havel = RelationshipTo('Leaf', 'Have')
have2 = RelationshipTo('Root', 'Have')
class Tree(StructuredNode):
name = StringProperty(unique_index=True)
ako = RelationshipTo('Plant', 'AKO')
have = RelationshipFrom('Fruiter', 'AKO')
class Grass(StructuredNode):
name = StringProperty(unique_index=True)
ako = RelationshipTo('Plant', 'AKO')
have = RelationshipFrom('Waterweeds', 'AKO')
class Leaf(StructuredNode):
name = StringProperty(unique_index=True)
have = RelationshipFrom('Plant', 'AKO')
class Root(StructuredNode):
name = StringProperty(unique_index=True)
have = RelationshipFrom('Plant', 'Have')
class Waterweeds(StructuredNode):
name = StringProperty(unique_index=True)
ako = RelationshipTo('Grass', 'AKO')
live = RelationshipTo('Water', 'AKO')
class Water(StructuredNode):
name = StringProperty(unique_index=True)
have = RelationshipFrom('Waterweeds', 'Live')
class Fruiter(StructuredNode):
name = StringProperty(unique_index=True)
ako = RelationshipTo('Tree', 'AKO')
can = RelationshipTo('Bear', 'Can')
have = RelationshipFrom('Pear', 'AKO')
class Bear(StructuredNode):
name = StringProperty(unique_index=True)
have = RelationshipFrom('Fruiter', 'Can')
class Pear(StructuredNode):
name = StringProperty(unique_index=True)
ako = RelationshipTo('Fruiter', 'AKO')
can = RelationshipTo('BearPear', 'Can')
class BearPear(StructuredNode):
name = StringProperty(unique_index=True)
have = RelationshipFrom('Pear', 'Can')
# 根据类生成实例
plant = Plant(name="植物").save()
tree = Tree(name="树").save()
grass = Grass(name="草").save()
leaf = Leaf(name="叶").save()
root = Root(name="根").save()
waterweeds = Waterweeds(name="水草").save()
water = Water(name="水").save()
fruiter = Fruiter(name="果树").save()
bear = Bear(name="结果").save()
pear = Pear(name="梨树").save()
bearpear = BearPear(name="结梨").save()
# 创建实例之间的连接关系
pear.ako.connect(fruiter)
pear.can.connect(bearpear)
fruiter.ako.connect(tree)
fruiter.can.connect(bear)
waterweeds.ako.connect(grass)
waterweeds.live.connect(water)
plant.havel.connect(leaf)
plant.have2.connect(root)
tree.ako.connect(plant)
grass.ako.connect(plant)