NoSQL你知道Neo4j吗?

272 阅读11分钟

Neo4j Graph Database

最近公司可能想做知识图谱+智能搜索,所以提前做好相关领域知识的学习,做好相关知识、技术的储备。

参考

Neo4j

一、安装使用

下载地址:neo4j.com/download-ce…

windows选择桌面版,选择windows版本下载安装

上手测试

网页访问:http://localhost:7474/browser/,或者:直接应用中点击Neo4j Browser

官方有两个例子,其中一个就是Movie的图关系建模。编辑器文本框输入:play movies 就可以查看这个demo。

案例

  • 构建知识图谱,实现智能问答

    【问】请问我需要使用Neo4j结合spring boot以及java语言,将红楼梦中的关系利用Neo4j构建知识图谱,实现一个智能问答系统,请问详细的实现步骤是什么
    【答】
    1. 数据预处理
    - 整理红楼梦中的人物、场景、事件等结构化数据。可以手动整理或利用NLP工具抽取。
    - 数据可存储为CSV,方便读取。
    2. 构建知识图谱
    - 使用Neo4j Java API加载数据,构建节点和关系。人物、场景为节点,关系如夫妻、兄弟等。
    - 创建索引和约束,方便查询。
    3. Spring Boot集成
    - 创建Spring Boot项目,引入Neo4j和NLP相关依赖。
    - 配置Neo4j数据库连接。
    - 创建服务调用Neo4j API进行CRUD操作。
    4. 问答系统服务
    - 创建问答对样例数据,训练 Chatbot 模型。
    - 实现问句解析服务,提取查询意图和信息。
    - 实现基于Neo4j的查询服务,根据解析结果在知识图谱中搜索答案。
    - 组装响应,返回答案。
    5. 优化与改进
    - 新增问答样例,逐步完善Chatbot。
    - 优化知识图谱,增加节点关系。
    - 优化查询,使用图算法提高效率。
    
  • 常见案例

【问】:使用spring boot 结合Neo4j可以做哪些有意思的demo
【答】:音乐播放器:构建一个音乐播放器demo,使用Neo4j存储歌曲、歌手和专辑之间的关系。用户可以搜索和播放歌曲、查看歌手和专辑信息,并与其他用户共享和交流歌曲和歌手的推荐。

【问】:请问上面提到的音乐播放器这个使用mysql和neo4j各自适用的场景是什么
【答】:MySQL 和 Neo4j 都是用于处理和存储数据的数据库管理系统,但它们在处理和存储数据方面具有不同的优势和适用场景。
对于音乐播放器这个示例,以下是 MySQL 和 Neo4j 各自适用的场景:
MySQL:
    音乐播放器的曲库管理:MySQL 适合存储和管理音乐文件和曲库。它可以存储歌曲的元数据(例如标题、艺术家、专辑等)以及歌曲文件的二进制数据。
    用户登录和权限管理:MySQL 通常用于处理用户登录和权限管理。它支持创建用户表,存储用户信息和登录凭据,并提供查询和验证用户登录请求的功能。
    曲库搜索和筛选:MySQL 提供了灵活的查询和筛选功能,可以根据歌曲的元数据(例如艺术家、专辑、风格等)进行搜索和筛选。
Neo4j:
    社交功能:Neo4j 适合实现音乐播放器的社交功能。它支持图模型存储,可以轻松地表示用户、歌曲和推荐之间的复杂关系。通过使用 Neo4j,可以实现歌曲推荐、相似艺术家推荐、用户间的社交互动等功能。
    推荐系统:Neo4j 可以用于实现基于图模型的推荐系统。通过分析用户、歌曲和推荐之间的复杂关系,可以为用户提供个性化的歌曲推荐服务。
    需要注意的是,在实际应用中,音乐播放器需要同时处理关系型数据(例如用户和歌曲之间的关系)和大量二进制数据(例如歌曲文件)。因此,建议将 MySQL 和 Neo4j 结合使用,以充分发挥它们各自的优势。MySQL 可以用于存储和管理音乐文件和曲库,而 Neo4j 可以用于处理复杂的社交关系和推荐系统。

【问】:就这个例子,请问基于Neo4j的推荐系统如何实现,请列举步骤,结合springboot
【答】:基于Neo4j的推荐系统可以通过以下步骤实现:
    创建节点和关系:在Neo4j数据库中,使用Cypher查询语言创建节点和关系。例如,可以创建一个用户节点和一个歌曲节点,并使用关系将它们连接起来。可以创建更多的节点和关系来表示用户、歌曲和其他实体之间的复杂关系。
    构建推荐模型:使用Neo4j的图算法和机器学习库来构建推荐模型。例如,可以使用基于图的协同过滤算法来分析用户和其他用户之间的相似度,并基于这些相似度来推荐歌曲。还可以使用基于内容的推荐算法来基于歌曲的属性(例如风格、情绪等)来推荐其他相似的歌曲。
    实现推荐接口:使用Spring Boot框架来实现推荐接口。可以使用Spring Boot的RESTful API来接收用户输入并根据推荐模型生成推荐结果。可以将推荐结果以JSON或其他格式返回给客户端。
    集成推荐接口:将推荐接口集成到音乐播放器的前端应用程序中。可以使用JavaScript或其他前端框架来调用推荐接口,并在前端展示推荐结果。可以结合前端交互和数据可视化技术来提供更好的用户体验。
    优化和调整:根据实际应用情况对推荐系统进行优化和调整。可以调整推荐模型的参数、添加更多的节点和关系、使用更复杂的算法和模型来提高推荐准确性和效果。
    需要注意的是,这只是一个简单的示例,实际的推荐系统需要考虑更多的因素,例如数据清洗、数据隐私和安全性、系统性能和可扩展性等。

二、基本CQL语法

更多cypher语法请参考:neo4j.com/docs/cypher…

或者参考W3CSchool

别人笔记:blog.csdn.net/qq_19283249…

基础命令

CQL命令用法
CREATE创建节点、关系和属性
MATCH检索有关节点、关系和属性数据
RETURN返回查询结果
WHERE提供条件过滤检索数据
DELETE删除节点和关系
REMOVE删除节点、关系的属性
ORDER BY排序检索数据
SET添加或者更新标签

常用命令

  • 使用cypher语言来描述关系

    ()小括号表示一个节点

    ->或<-表示关系,[]为关系的描述,:后面为关系的标签

    (fox)<-[:knows]-(周瑜)-[:knows]->(诸葛)->[:knows]->(fox)
    
LOAD CSV
// 从csv文件中创建节点
LOAD CSV FROM 'file:///test.csv' AS line
create (:TastObj {name:line[0], age:line[1]})
RETURN linenumber() AS number, line
CREATE
// 创建节点
create (:Student{name:"张三", age:11}), (:Student{name:"李四", age:33}), (:Student{name:"王五", age:33})

// 创建关系
match (zs:Student{name:"张三"}), (ls:Student{name:"李四"}), (ww:Student{name:"王五"})
create (ww)-[:大哥]->(zs), (ww)-[:二哥]->(ls), (ls)-[:大哥]->(zs), (zs)-[:小弟]->(ls), (zs)-[:小弟]->(ww), (ls)-[:小弟]->(ww)
return zs.name, ls.name, ww.name

// 创建全路径

DELETE
// 删除节点(存在关系删除不掉)
MATCH (n:Student{name:"张三"}) delete n

// 删除关系
MATCH (n:Student{name:"张三"})<-[r]-(m) delete r return type(r)
MATCH (n:Student{name:"张三"})-[r]->(m) delete r return type(r)
MATCH (n:Student)<-[r]-(m:Student) where n.name = '张三' and m.name = '李四' delete r return type(r)

// 删除指定节点和关系
MATCH (n:Student) WHERE n.name = '张三'
DETACH DELETE n
SET、REMOVE
// 设置属性
match (stu:Student{name:"张三"}) set stu.age = 11 return stu.age

// 移除属性
match (stu:Student{name:"张三"}) remove stu.age return stu.name
MATCH
// 查询并返回数据
// eg1:直接根据属性查询
match (zs:Student{name:"张三"}), (ls:Student{name:"李四"}), (ww:Student{name:"王五"})
return zs.name, ls.name, ww.name
WHERE
// id(xxx)查询节点ID
match (stu:Student) where stu.name = '张三' or stu.name = '李四' or stu.name = '王五'
return id(stu), stu.name  LIMIT 2

// neo4j 单个模糊查询
// eg1.匹配关系
MATCH p=()-[r:company_notice]->() where r.CATE=~'.*反.*' RETURN p 
// eg2.匹配节点
// 单个节点
match (n:notice) where n.TITLE=~'.*2008.*' return n
// 多个节点
match (n:notice) where n.TITLE=~'.*2008.*|.*2007.*' return n

// 使用关键字 starts with、 ends with、Contains 进行表示
// eg1.匹配关系
MATCH p=()-[r:company_notice]->() where r.CATE starts with '反' or r.CATE ends with '销' or r.CATE Contains '反' RETURN p 
// eg2.匹配节点
match (n:notice) where n.TITLE starts with '海' or n.TITLE ends with '洋' or n.TITLE Contains '2008' return n
LIMIT、SKIP
// LIMIT 限制条数
// SKIP 跳过前几条
MATCH p=()-[r:`二哥`]->() RETURN p LIMIT 25
MATCH p=()-[r:`二哥`]->() RETURN p SKIP 2
IN
match (stu:Student) where stu.name in ['张三','李四'] return stu.name
DISTINCT
// 结果去重
match (stu:Student) return distinct(stu.name)
NULL
// 设置属性为空
match (stu:Student{name:"张三"}) set stu.friend = "李四" return stu.name, stu.friend
match (stu:Student{name:"李四"}) set stu.friend = null return stu.name, stu.friend
// 查询属性为空的节点
match (stu:Student) where stu.friend is null return stu.name, stu.friend
match (stu:Student) where stu.friend is not null return stu.name, stu.friend
INDEX
// eg1:创建索引
create index on :Student(name)
// eg2:删除索引
drop index on :Student(name)
match (stu:Student) where stu.name = '张三' return stu.name
UNIQUE
// eg1:添加唯一约束
create constraint on (n:Student) assert n.name is unique、
// eg2:删除唯一约束
drop constraint on (n:Student) assert n.name is unique
完整示例
// 从csv文件中创建节点
LOAD CSV FROM 'file:///test.csv' AS line
create (:TastObj {name:line[0], age:line[1]})
RETURN linenumber() AS number, line

// 创建节点
create (:Student{name:"张三", age:11}), (:Student{name:"李四", age:33}), (:Student{name:"王五", age:33})

// 创建关系
match (zs:Student{name:"张三"}), (ls:Student{name:"李四"}), (ww:Student{name:"王五"})
create (ww)-[:大哥]->(zs), (ww)-[:二哥]->(ls), (ls)-[:大哥]->(zs), (zs)-[:小弟]->(ls), (zs)-[:小弟]->(ww), (ls)-[:小弟]->(ww)
return zs.name, ls.name, ww.name

// 查询并返回数据
// eg1:直接根据属性查询
match (zs:Student{name:"张三"}), (ls:Student{name:"李四"}), (ww:Student{name:"王五"})
return zs.name, ls.name, ww.name
// eg2:使用where条件查询
// id(xxx)查询节点ID
match (stu:Student) where stu.name = '张三' or stu.name = '李四' or stu.name = '王五'
return id(stu), stu.name  LIMIT 2
// eg3:查询关系
// LIMIT 限制条数
// SKIP 跳过前几条
MATCH p=()-[r:`二哥`]->() RETURN p LIMIT 25

// 删除节点(存在关系删除不掉)
MATCH (n:Student{name:"张三"}) delete n

// 删除关系
MATCH (n:Student{name:"张三"})<-[r]-(m) delete r return type(r)
MATCH (n:Student{name:"张三"})-[r]->(m) delete r return type(r)
MATCH (n:Student)<-[r]-(m:Student) where n.name = '张三' and m.name = '李四' delete r return type(r)

// 删除指定节点和关系
MATCH (n:Student) WHERE n.name = '张三'
DETACH DELETE n

// 移除属性
match (stu:Student{name:"张三"}) remove stu.age return stu.name

// 设置属性
match (stu:Student{name:"张三"}) set stu.age = 11 return stu.age

// 根据属性排序
match (stu:Student) where stu.name = '张三' or stu.name = '李四' or stu.name = '王五'
return id(stu), stu.name order by id(stu) desc LIMIT 10
match (stu:Student) where stu.name = '张三' or stu.name = '李四' or stu.name = '王五'
return id(stu), stu.name, stu.age order by stu.age desc LIMIT 10

// UNION组装数据
match (stu:Student) where stu.name = '张三'  return stu.name
union
match (stu:Student) where stu.name = '李四'  return stu.name

// NULL
match (stu:Student{name:"张三"}) set stu.friend = "李四" return stu.name, stu.friend
match (stu:Student{name:"李四"}) set stu.friend = null return stu.name, stu.friend
match (stu:Student) where stu.friend is null return stu.name, stu.friend
match (stu:Student) where stu.friend is not null return stu.name, stu.friend

// IN
match (stu:Student) where stu.name in ['张三','李四'] return stu.name

// INDEX索引
// eg1:创建索引
create index on :Student(name)
// eg2:删除索引
drop index on :Student(name)
match (stu:Student) where stu.name = '张三' return stu.name

// UNIQUE唯一约束
// eg1:添加唯一约束
create constraint on (n:Student) assert n.name is unique、
// eg2:删除唯一约束
drop constraint on (n:Student) assert n.name is unique

// DISTINCT去重
match (stu:Student) return distinct(stu.name)

常用函数

函数用法
String字符串用于对字符串处理
Aggregation聚合用于对CQL查询结果进行聚合操作
Relationship关系用于获取关系的细节,如:startnode、endnode等
字符串函数
  • upper
  • lower
  • substring
  • replace
match (stu:Student) retuen id(stu), stu.name, substring(stu.name, 0, 2)
聚合函数
  • count
  • max
  • min
  • sum
  • avg
match (stu:Student) return count(stu) as count1, max(stu.age) as age
关系函数
  • startnode:获取关系的开始节点
  • endnode:获取关系的结束节点
  • id:获取关系ID
  • type:获取关系的TYPE
match (a)-[r]->(b) return id(r),type (r)

Neo4j-admin的使用

数据库备份
  • 对Neo4j数据进行备份、还原、迁移操作时,要关闭Neo4j

    cd %NEO4J_HOME%/bin
    # 关闭neo4j(注意一定要先install服务:neo4j install-service)
    neo4j stop
    # 备份
    neo4j-admin dump --database=graph.db --to=/neo4j/backup/graph_backup.dump
    
数据库恢复
  • 还原、请按一之前,要关闭neo4j服务

    # 数据导入
    neo4j-admin load --from=/neo4j/backup/graph_backup.dump --database = graph.db --force
    # 重启服务
    neo4j start
    

案例

// 删除所有节点和关系
MATCH (n)
DETACH DELETE n

// load文件创建实体
LOAD CSV FROM 'file:///hl_relationship.csv' AS line 
MERGE (:人物 {name:line[0], family:line[3]})
MERGE (:人物 {name:line[1], family:line[4]})
MERGE (:关系 {from:line[0], to:line[1], relation:line[2]})
MERGE (:家族 {name:line[3]})
return line

// 创建实体之间关系
// 人物关系
match (m: 人物), (n: 人物), (r: 关系) where m.name = r.from and n.name = r.to
MERGE (m)-[:relation{relationship:r.relation}]->(n)
return m.name, n.name, r.relation
// 人物和家族的关系
match (m: 人物), (n: 家族) where n.name = m.family
MERGE (m)-[:relation{relationship:"family"}]->(n)
return m.name, n.name