先可视化的看一下 掘金酱 有没有关注你。。。
简介
Neo是一个网络——面向网络的数据库——也就是说,它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络上而不是表中。网络(从数学角度叫做图)是一个灵活的数据结构,可以应用更加敏捷和快速的开发模式。
- 开源,支持ACID,具有用于企业部署的高可用性集群。
- 附带基于Web的管理工具,包括完整事务支持和可视节点链接图浏览器;
- 内置的REST Web API接口从大多数编程语言访问,以及使用官方驱动程序的专有Bolt协议;
Neo4j 安装
推荐 Docker 安装 Docker Hub 地址。
Docker 安装的优势有:
- 不依赖宿主机任何语言环境,只需要安装 docker。
- 部署方便,一行命令即可实现部署。
- 配置简单,不需要配置 环境变量、资源参数等莪皮质。
- 随时重启恢复,遇到问题可以快速恢复。
# 在装有 docker 环境的电脑上直接启动
docker run -p 7474:7474 -p 7687:7687 -v /d/docker/neo4j:/data --restart=always neo4j
安装成功后浏览器访问 http://localhost:7474/ 进行初始化设置:
- 输入默认的用户名密码
neo4j/neo4j - 修改密码为
admin - 再次登录进系统
Cypher 查询
Cypher 类似 Mysql 数据库具有查询语言 SQL,Neo4j 具有 CQL 作为查询语言。
这里只演示简单的语句,详细的语句见 Neo4j 文档
创建对象
# 创建一个名称为张三的 Person 对象
CREATE (:Person {name:"张三"});
# 建立张三关注李四的关系
MATCH (a:Person {name: "张三"}) MATCH (b:Person {name: "李四"}) MERGE (a)-[:Follower]->(b);
查询对象
# 返回所有 Person 对象
MATCH (p:Person) RETURN p;
# 查询 name="张三" 的 Person 对象
MATCH (p:Person) where p.name="张三" RETURN p;
# 查询两个节点之间关系为 Follower 的所有 Person 对象
MATCH(p1:Person) - [:Follower]->(p2:Person) return p1,p2;
删除对象
# 删除所有 Person 对象
MATCH(p:Person) DETACH DELETE p;
修改对象
# name 为张三 的 Person 对象新增 age 属性且替换 name属性
MATCH (p:Person{name:"张三"}) set p={name:"张三"} return p;
# name 为张三 的 Person 对象新增 age 属性
MATCH (p:Person{name:"张三"}) set p+={name:"张三"} return p;
创建索引
# 为Person 对象 name 属性创建索引
CREATE INDEX ON :Person(name);
Python 构建数据
数据准备
这里采用的数据为掘金的关注数据,所以先封装掘金获取关注者的接口
import requests
class JueJin(object):
followers_url = "https://api.juejin.cn/user_api/v1/follow/followers"
followees_url = "https://api.juejin.cn/user_api/v1/follow/followees"
def __init__(self):
self.session = requests.session()
def get_followers(self, user_id, cursor, limit):
params = {
"user_id": user_id,
"cursor": cursor,
"limit": limit
}
return self.session.request("get", self.followers_url, params=params).json()
def get_followees(self, user_id, cursor, limit):
params = {
"user_id": user_id,
"cursor": cursor,
"limit": limit
}
return self.session.request("get", self.followees_url, params=params).json()
封装查询语句
为了操作简单这里封装基本的查询语言:
from neo4j import GraphDatabase
class App(object):
def __init__(self, uri, username, password):
self.driver = GraphDatabase.driver(uri, auth=(username, password))
def close(self):
self.driver.close()
@classmethod
def create_person(cls, tx, name):
tx.run("CREATE (:Person {name: $name})", name=name)
@classmethod
def create_friendship(cls, tx, name_a, name_b):
tx.run("MATCH (a:Person {name: $name_a}) "
"MATCH (b:Person {name: $name_b}) "
"MERGE (a)-[:Follower]->(b)",
name_a=name_a, name_b=name_b)
@classmethod
def delete_person(cls, tx):
tx.run("MATCH(p:Person) DETACH DELETE p;", )
@staticmethod
def _find_and_return_person(tx, name):
query = (
"MATCH (p:Person) "
"WHERE p.name = name "
"RETURN p.name AS name"
)
result = tx.run(query, name=name)
return [record["name"] for record in result]
批量创建节点
def main():
# Connecting to Aura, use the "neo4j+s" URI scheme
scheme = "neo4j"
host_name = "deepin"
port = 7687
url = "{scheme}://{host_name}:{port}".format(scheme=scheme, host_name=host_name, port=port)
user = "neo4j"
# 这里输入你设置的密码
password = "admin"
app = App(url, user, password)
juejin = JueJin()
# 你想看哪位掘友的就替换为对应掘友的信息
user_id, user_name = "993614678985085", "西红柿蛋炒饭"
cursor, limit = 0, 20
followees, followers = [], []
has_more = True
while has_more:
result = juejin.get_followees(user_id, cursor, limit)
data = result['data']['data']
followees += data
has_more = result['data']['hasMore']
cursor = result['data']['cursor']
cursor, limit = 0, 20
has_more = True
while has_more:
result = juejin.get_followers(user_id, cursor, limit)
data = result['data']['data']
followers += data
has_more = result['data']['hasMore']
cursor = result['data']['cursor']
names = {f["user_name"] for f in followees + followers}
with app.driver.session() as session:
session.write_transaction(app.delete_person)
session.write_transaction(
app.create_person, user_name)
for name in names:
session.write_transaction(
app.create_person, name)
for person in followees:
session.write_transaction(
app.create_friendship, user_name, person['user_name'])
for person in followers:
session.write_transaction(
app.create_friendship, person['user_name'], user_name)
app.close()
查看结果
所有节点数据 MATCH(p:Person) return p;
互相关注节点数据 MATCH(p1:Person) - [:Follower]->(p2:Person) - [:Follower]->(p1:Person) return p1,p2;
最后
这里只是演示了最简单的使用,实际上关于 Neo4j 的用处有很多,非常值得探索,下面分享一下我异想天开的想法:
-
- 构建掘金用户的关系图,看看你与我之间到底隔了几个掘友。
-
- 可以用来做搜索推荐,推荐你关注的掘友关注的掘友喜欢的文章。
-
- 可以可视化的显示你关注的掘友关注的掘友,顺便去关注这位掘友。
当然这些想法都是基于海量的掘友数据完成了,这又是个体力活。emm 就这样吧。
如果你觉得我的项目对你有帮助,欢迎一键三连❤️❤️❤️。此项目代码见 GitHub ,也欢迎 star fork。