Neo4j 图数据库搭建教程

Neo4j 是最流行的原生图数据库,使用节点(Node)和关系(Relationship)来存储和查询数据,特别适合社交网络、推荐系统、知识图谱、欺诈检测等需要复杂关系查询的场景。相比关系型数据库中多表 JOIN 的低效查询,图数据库可以在毫秒级完成多跳关系遍历。本文将在搬瓦工 VPS 上部署 Neo4j 并讲解 Cypher 查询语言。

一、安装 Neo4j

1.1 APT 安装

# 安装 Java(Neo4j 5.x 需要 Java 17)
apt install openjdk-17-jre-headless -y

# 添加 Neo4j 仓库
wget -O - https://debian.neo4j.com/neotechnology.gpg.key | apt-key add -
echo 'deb https://debian.neo4j.com stable latest' | tee /etc/apt/sources.list.d/neo4j.list
apt update
apt install neo4j -y

1.2 Docker 安装

docker run -d --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -e NEO4J_AUTH=neo4j/YourPassword123! \
  -e NEO4J_PLUGINS='["apoc"]' \
  -e NEO4J_server_memory_heap_max__size=512m \
  -v neo4j_data:/data \
  --restart unless-stopped \
  neo4j:5-community

二、配置

编辑 /etc/neo4j/neo4j.conf

# 监听地址
server.default_listen_address=0.0.0.0

# 内存配置(搬瓦工 2GB 方案)
server.memory.heap.initial_size=256m
server.memory.heap.max_size=512m
server.memory.pagecache.size=256m

# Bolt 协议端口
server.bolt.listen_address=0.0.0.0:7687

# HTTP 端口(浏览器访问)
server.http.listen_address=0.0.0.0:7474
# 启动服务
systemctl start neo4j
systemctl enable neo4j

# 首次登录修改密码
cypher-shell -u neo4j -p neo4j
ALTER CURRENT USER SET PASSWORD FROM 'neo4j' TO 'YourPassword123!';

Web 浏览器界面:http://your-server-ip:7474

三、Cypher 查询语言基础

3.1 创建节点和关系

// 创建用户节点
CREATE (u1:User {name: '张伟', age: 28, city: '北京'})
CREATE (u2:User {name: '李明', age: 25, city: '上海'})
CREATE (u3:User {name: '王芳', age: 30, city: '北京'})

// 创建关系
MATCH (a:User {name: '张伟'}), (b:User {name: '李明'})
CREATE (a)-[:FOLLOWS {since: '2025-01-01'}]->(b)

MATCH (a:User {name: '李明'}), (b:User {name: '王芳'})
CREATE (a)-[:FOLLOWS {since: '2025-06-15'}]->(b)

MATCH (a:User {name: '张伟'}), (b:User {name: '王芳'})
CREATE (a)-[:FRIEND_OF {since: '2024-03-01'}]->(b)

// 创建内容节点和互动关系
CREATE (p1:Post {title: 'Neo4j 入门', content: '图数据库很强大', created_at: datetime()})

MATCH (u:User {name: '张伟'}), (p:Post {title: 'Neo4j 入门'})
CREATE (u)-[:PUBLISHED]->(p)

MATCH (u:User {name: '李明'}), (p:Post {title: 'Neo4j 入门'})
CREATE (u)-[:LIKED]->(p)

3.2 查询数据

// 查询所有用户
MATCH (u:User) RETURN u;

// 查询关注关系
MATCH (a:User)-[:FOLLOWS]->(b:User)
RETURN a.name AS follower, b.name AS following;

// 查找朋友的朋友(二度关系)
MATCH (u:User {name: '张伟'})-[:FRIEND_OF*2]->(fof:User)
WHERE fof.name <> '张伟'
RETURN DISTINCT fof.name;

// 最短路径
MATCH path = shortestPath(
  (a:User {name: '张伟'})-[*..6]-(b:User {name: '王芳'})
)
RETURN path;

// 计算入度(被关注数)
MATCH (u:User)<-[:FOLLOWS]-(follower)
RETURN u.name, count(follower) AS followers
ORDER BY followers DESC;

四、实际应用:推荐系统

// 基于共同关注推荐用户
MATCH (me:User {name: '张伟'})-[:FOLLOWS]->(friend)-[:FOLLOWS]->(recommended)
WHERE NOT (me)-[:FOLLOWS]->(recommended) AND recommended <> me
RETURN recommended.name, count(friend) AS mutual_friends
ORDER BY mutual_friends DESC
LIMIT 5;

// 基于内容兴趣推荐
MATCH (me:User {name: '张伟'})-[:LIKED]->(post)<-[:LIKED]-(similar_user)-[:LIKED]->(rec_post)
WHERE NOT (me)-[:LIKED]->(rec_post)
RETURN rec_post.title, count(similar_user) AS score
ORDER BY score DESC LIMIT 10;

五、索引和约束

// 创建唯一约束
CREATE CONSTRAINT unique_user_name FOR (u:User) REQUIRE u.name IS UNIQUE;

// 创建索引
CREATE INDEX user_city FOR (u:User) ON (u.city);

// 全文索引
CREATE FULLTEXT INDEX post_content FOR (p:Post) ON EACH [p.title, p.content];

// 使用全文索引搜索
CALL db.index.fulltext.queryNodes('post_content', '图数据库') YIELD node, score
RETURN node.title, score;

// 查看所有索引
SHOW INDEXES;

六、Python 客户端

from neo4j import GraphDatabase

driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "YourPassword123!"))

def find_friends_of_friends(tx, name):
    result = tx.run("""
        MATCH (u:User {name: $name})-[:FRIEND_OF*2]->(fof:User)
        WHERE fof.name <> $name
        RETURN DISTINCT fof.name AS name
    """, name=name)
    return [record["name"] for record in result]

with driver.session() as session:
    fof = session.execute_read(find_friends_of_friends, "张伟")
    print(f"Friends of friends: {fof}")

driver.close()

七、APOC 扩展

// 安装 APOC 插件后可使用扩展函数

// 导出为 JSON
CALL apoc.export.json.all('/tmp/graph.json', {useTypes: true});

// 批量创建节点
CALL apoc.periodic.iterate(
  "UNWIND range(1, 10000) AS id RETURN id",
  "CREATE (:TestNode {id: id})",
  {batchSize: 1000}
);

八、备份与监控

# 停机备份
neo4j stop
neo4j-admin database dump neo4j --to-path=/data/backups/
neo4j start

# 查看数据库状态
CALL dbms.listDatabases();

# 查看查询统计
CALL dbms.listQueries();

九、性能优化

  • 索引策略:为 MATCH 查询中频繁用于查找起点的属性创建索引。
  • 查询优化:使用 PROFILE 前缀查看执行计划,避免笛卡尔积。
  • 内存调优:搬瓦工 1GB 方案建议 heap=256m、pagecache=128m。
  • 数据建模:将高频查询的属性直接放在关系上,减少遍历深度。
// 使用 PROFILE 分析查询
PROFILE MATCH (u:User {name: '张伟'})-[:FOLLOWS*1..3]->(friend)
RETURN friend.name;

十、常见问题

  • 内存不足:Neo4j 对内存需求较高。报 Java heap space 错误时需增大 heap 配置。
  • 查询超时:复杂的全图遍历可能非常耗时。使用路径长度限制(如 *1..5)控制遍历深度。
  • 数据量限制:社区版单库上限为 340 亿节点和关系,足够绝大多数场景。
  • 防火墙:需要开放 7474(HTTP)和 7687(Bolt)端口。
ufw allow 7474/tcp
ufw allow 7687/tcp

总结

Neo4j 是处理复杂关系数据的最佳工具,Cypher 查询语言直观易学。在搬瓦工 VPS 上部署后可以用于社交网络分析、推荐引擎、知识图谱等场景。选购搬瓦工 VPS 请查看 全部方案,使用优惠码 NODESEEK2026 享受 6.77% 折扣,通过 bwh81.net 进入官网。

关于本站

搬瓦工VPS中文网(bwgvps.com)是非官方中文信息站,整理搬瓦工的方案、优惠和教程。我们不销售主机,不提供技术服务。

新手必读
搬瓦工优惠码

NODESEEK2026(优惠 6.77%)

购买时填入即可抵扣。