Neo4j
文章目录
- Neo4j
- CQL
- 结点和关系
- 增删改查
- 匹配语句
- 根据标签匹配节点
- 根据标签和属性匹配节点
- 删除
- 导入数据
- 目前的问题
- 菜谱
- 解决的问题
命令行窗口 neo4j.bat console
导入rdf格式的文件
:GET /rdf/ping
CALL n10s.graphconfig.init(); //初始化
call n10s.rdf.import.fetch("file:///F:\\wow.rdf",'Turtle')// 导入注意斜杠///(本地文件需要用这个)
清空所有数据
这里要注意的是,因为不存在孤立的关系,所以若要删除一个带关系的节点,需要同时删除该节点所有的关系。
即,若要删除路径(a)-[d]-(b)-[e]-(c)
中的 a,b 节点,则需要同时删除关系 d,e。
因此,若要清空数据库,即删除所有的节点和关系,可以先使用 MATCH
找到所有的节点,再使用 OPTIONAL MATCH
查询节点是否存在关系,最后将其全部删除。
MATCH (n)
OPTIONAL MATCH (n)-[r]-()
DELETE n,r
return
因为 CREATE
命令可以允许不跟 RETURN
同时使用,若使用了 RETURN
,才会返回 Graph
界面
CQL
Neo4j的Cypher语言是为处理图形数据而构建的,CQL代表Cypher查询语言。像Oracle数据库具有查询 语言SQL,Neo4j具有CQL作为查询语言。
结点和关系
Cypher 采用一对圆括号 ()
来表示节点,如 (n:角色)
表示一个 角色
节点,n
是变量名,供命令执行时用 n
来访问这个节点,在命令执行完毕后就无法使用了。同时单独的 ()
表示一个匿名节点,在匹配时表示匹配所有节点。
在关系中
--
表示无方向的关系-->
表示有方向的关系-[r]->
则给关系赋予一个变量名,方便对这个关系进行操作-[r:配偶]->
匹配关系为配偶
的类型
增删改查
//建立结点
create(n:Person{name:"小江",sex:"男"}) return n
//建立关系 (小江是小王的爸爸)
MATCH(a:Person{name:"小江"}),(b:Person{name:"小王"})Merge(a)-[r:爸爸]->(b)
//创建节点的时候就建立好关系
CREATE (a:Person {name:'苗同学'})-[r:朋友]->(b:Person {name:'叶同学'})
//修改 把name是小王的name改成小江
Match (a:Person{name:"小王"})set a.name="小江"
//搜索 信息是大学生的,返回改结点
match(a:Person{info:"大学生"}) return a
//在一个结点中建立新的属性,在名字为小陈这个结点添加info属性
match (a:Person{name:"小陈"}) set a.info="小学生"
//删除结点的某个属性
match (a:Person{name:"小陈"}) remove a.info
//删除关系
match(a:Person{name:"小陈"})-[r:`爸爸`]-(b:Person{name:"江"}) delete r
//删除结点 To delete this node, you must first delete its relationships.删除结点前要先删除关系
match (a:Person{name:"小江"}) delete a
merge
与create
的区别
可以认为 MERGE = MATCH + CREATE
,因此,在对图数据进行添加时,若想要跳过已存在的节点或关系,使用 MERGE
命令,若不关心重复节点或关系,则使用 CREATE
命令
匹配语句
// 匹配 name 为 郭靖 的 角色 节点
match (n:角色{name:'郭靖'}) return n
删除
Neo4j 中有两种删除方法,DELETE
和 REMOVE
。DELETE
用于删除节点和关系,REMOVE
用于删除节点和关系的标签与属性。两者都需要配合 MATCH
,先匹配到内容,再执行操作。
删除节点
若要删除节点,则需要删除与节点相关的所有边,这与图论一致——不存在没有节点的边。 因此要删掉金轮法王这个节点,就先需要找到该节点和所在关系,再进行删除
match(n:`角色`{name:"王重阳"})-[r]-() delete n,r
导入数据
load csv with headers from 'file:///data\\射雕三部曲.csv' as line
match (book:作品),(person:角色),(skill:武功)wherebook.name in split(line.作品, ',') andperson.name = line.人物 andskill.name in split(line.武功, ',')
optional match (father:角色)wherefather.name = line.父
optional match (mother:角色)wheremother.name = line.母
optional match (spouse:角色)wherespouse.name = line.配偶
optional match (sect:门派)wheresect.name = line.门派
optional match (children:角色)wherechildren.name in split(line.子女, ',')
optional match (master:角色)wheremaster.name in split(line.师傅, ',')
merge (person)-[:所在作品]-(book)
merge (person)-[:师傅]-(master)
merge (person)-[:武功]-(skill)
merge (person)-[:父]-(father)
merge (person)-[:母]-(mother)
merge (person)-[:配偶]->(spouse)
merge (person)-[:所在门派]-(sect)
merge (person)-[:子女]-(children)
目前的问题
1.高血压最重要的营养素是钾和钠,但是我们之前那个数据里面是没有钾元素的
两个数据,分开建图是可以的,但是合起来不行欸
我的想法是先建立原料和营养的图,然后再建立菜和原料的图,如果这个原料有的话,就连接过去
可以建立类别,然后富含的话可以放在钾元素那里,还有少量,放在钠元素,其他的话要有含量吧,写在关系中吗
菜谱
load csv with headers from 'file:///data\\export.csv' as line
merge(n:食物{name:line.食物名,kind:line.分类}) return n
create(n:营养素{name:"钠"}) return n //建立营养素
解决的问题
1.新版的python连接图数据库的写法
网上很多都是这个,但是我会报错
graph = Graph("http://localhost:7474", username="root", password='123456')
原因是python版本问题,下面这个是正确的写法
graph = Graph('http://localhost:7474', auth=("neo4j", "123456"))
2.报错:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xaa in position
就是编码方式的问题
with open("D:\\neo4j-community-4.4.14-windows\\neo4j-community-4.4.14\\import\\data\\export.csv", 'r',encoding='utf-8') as f:
最后要加上enconding='utf-8’就可以了
match (a:nutrients)-[:富含]-(b:recipe_matrial{name:"生菜"})-[:include]-(c:recipe) return a,b,c
match (a:recipe{name:"蚂蚁上树"})-[:include]-(b:recipe_matrial)-[:have]-(c) return a,b,c
match(a:食材{name:{foodName}})-[:推荐食用]-(b:疾病) return a,b
查找钵钵鸡的所有关系,但是只有一层
match (n:recipe{name:"蚂蚁上树"})--(b) return n,b
两层关系
match (n:recipe{name:"蚂蚁上树"})--(b)-->(c) return n,b,c
match n=(x:recipe)-[*1..2]-() where x.name="钵钵鸡" return n
如果是直接通过菜找营养素的话,就没有钠含量了
如果通过菜找食材再找营养素的话,这两个数据是分开的,有些食材在另一个数据里是没有的
if question_type == 'disease_cause':sql = ["MATCH (m:Disease) where m.name = '{0}' return m.name, m.cause".format(i) for i in entities]