from neo4j import GraphDatabase from neo4j.graph import GraphAlgorithm
# 计算 PageRank defpagerank(session): result = session.run(""" CALL algo.pageRank('Person', 'KNOWS', {iterations: 20, dampingFactor: 0.85}) YIELD nodeId, score RETURN algo.asNode(nodeId).name AS name, score ORDER BY score DESC """) returnlist(result)
# 社区发现(Louvain 算法) defcommunity_detection(session): result = session.run(""" CALL algo.louvain('Person', 'KNOWS', {includeIntermediateCommunities: true}) YIELD nodeId, community, communities RETURN algo.asNode(nodeId).name AS name, community ORDER BY community """) returnlist(result)
// 日期时间处理 MATCH (p:Person) SET p.born = apoc.date.parse("1971-05-15", "ms", "yyyy-MM-dd")
// 字符串处理 MATCH (p:Person) SET p.name_upper = apoc.text.toUpperCase(p.name)
// 地理处理 MATCH (c:Company) WHERE apoc.spatial.distanceWithin( c.location, {lat: 22.5431, lon: 114.0579}, 100 ) RETURN c
2.4 Neo4j AuraDB(云服务)
1 2 3 4 5 6 7 8 9 10 11
# 使用 Neo4j AuraDB(无需安装) from neo4j import GraphDatabase
# AuraDB 连接字符串 URI = "neo4j+s://xxxxxxxx.databases.neo4j.io" AUTH = ("neo4j", "password")
with GraphDatabase.driver(URI, auth=AUTH) as driver: with driver.session() as session: result = session.run("MATCH (n) RETURN count(n)") print(result.single()[0])
-- 创建 Schema CREATE VERTEX Person (PRIMARY_ID name STRING, name STRING, age INT) CREATE VERTEX Company (PRIMARY_ID name STRING, name STRING, founded INT) CREATE EDGE FOUNDED (FROM Person, TO Company, yearINT)
-- 插入数据 INSERT INTO Person VALUES ("MH", "马化腾", 1971) INSERT INTO Person VALUES ("LS", "李彦宏", 1968) INSERT INTO Person VALUES ("ZD", "张志东", 1972) INSERT INTO COMPANY VALUES ("Tencent", "腾讯", 1998) INSERT INTO COMPANY VALUES ("Baidu", "百度", 2000) INSERT INTO FOUNDED VALUES ("MH", "Tencent", 1998) INSERT INTO FOUNDED VALUES ("LS", "Baidu", 2000)
-- 查找"某人的二度人脉" MATCH (me:Person {name: "张三"})-[:KNOWS*2..2]-(friend_of_friend) WHERE NOT (me)-[:KNOWS]-(friend_of_friend) RETURN DISTINCT friend_of_friend.name
-- 查找共同好友 MATCH (a:Person {name: "张三"})-[:KNOWS]-(friend)-[:KNOWS]-(b:Person {name: "李四"}) RETURN friend.name AS mutualFriend
-- 推荐可能认识的人 MATCH (me:Person {name: "张三"})-[:KNOWS]-()-[:KNOWS]-(suggestion) WHERE NOT (me)-[:KNOWS]-(suggestion) AND me <> suggestion RETURN suggestion.name, count(*) AS commonFriends ORDER BY commonFriends DESC LIMIT 5
6.2 推荐系统
1 2 3 4 5 6 7 8
-- 基于知识图谱的商品推荐 -- 用户买了"手机" → 推荐相关配件 MATCH (u:User {id: 123})-[:PURCHASED]->(p:Product {name: "iPhone"}) MATCH (p)-[:CATEGORY]->(cat:Category)<-[:CATEGORY]-(related:Product) WHERE NOT (u)-[:PURCHASED]->(related) RETURN related.name, collect(cat.name) AS categories ORDER BY size(collect(cat.name)) DESC LIMIT 10
6.3 金融风控
1 2 3 4 5 6 7 8 9 10 11 12
-- 检测洗钱:资金在短时间内多次中转 MATCH path = (source:Account)-[:TRANSFER*3..5]->(target:Account) WHERE duration.inDays(path.startDate, path.endDate) < 7 AND source <> target AND ALL(r IN relationships(path) WHERE r.amount > 10000) RETURN path
-- 团伙欺诈检测:共用设备+共用账户 MATCH (fraud1:Fraud)-[:USED_DEVICE]->(d:Device)<-[:USED_DEVICE]-(fraud2:Fraud) MATCH (fraud1)-[:HAS_ACCOUNT]->(a:Account)<-[:HAS_ACCOUNT]-(fraud2) WHERE fraud1 <> fraud2 RETURN fraud1.id, fraud2.id, collect(DISTINCT d.deviceId) AS sharedDevices
6.4 知识图谱
1 2 3 4
-- 知识推理:X 是 Y 的竞争对手,Y 是 Z 的竞争对手 → X 和 Z 是? MATCH (x:Company)-[:COMPETITOR]->(y:Company)-[:COMPETITOR]->(z:Company) WHERE NOT (x)-[:COMPETITOR*0..1]->(z) CREATE (x)-[:POTENTIAL_COMPETITOR]->(z)
七、图数据库性能优化
7.1 索引优化
1 2 3 4 5 6 7 8 9 10 11
-- Neo4j:为高频查询属性创建索引 CREATE INDEX person_name IF NOT EXISTS FOR (p:Person) ON (p.name) CREATE INDEX company_id IF NOT EXISTS FOR (c:Company) ON (c.id)