图数据库架构
图数据库架构
属性图模型
属性图由节点、边和属性组成,适合表达实体间的复杂关系。
(Alice)-[:FRIEND]->(Bob)-[:WORKS_AT]->(Company)
(Alice)-[:LIKES]->(Product)<-[:SELLS]-(Company)
@Configuration
public class Neo4jConfig {
@Bean
public Driver neo4jDriver() {
return GraphDatabase.driver(
"bolt://localhost:7687",
AuthTokens.basic("neo4j", "password"));
}
}
Cypher查询语言
Cypher是Neo4j的声明式查询语言,用模式匹配表达图查询。
@Repository
public interface PersonRepository extends Neo4jRepository<Person, Long> {
@Query("MATCH (p:Person)-[:FRIEND]->(f:Person) WHERE p.name = $name RETURN f")
List<Person> findFriendsByName(@Param("name") String name);
@Query("MATCH (p:Person)-[:FRIEND*1..3]->(f:Person) WHERE p.name = $name RETURN DISTINCT f")
List<Person> findFriendsWithinThreeHops(@Param("name") String name);
}
// 创建节点和关系
CREATE (alice:Person {name: 'Alice', age: 30})
CREATE (bob:Person {name: 'Bob', age: 25})
CREATE (alice)-[:FRIEND {since: 2020}]->(bob)
// 查找最短路径
MATCH path = shortestPath(
(a:Person {name: 'Alice'})-[*]-(b:Person {name: 'Charlie'})
)
RETURN path
// 社区发现算法
CALL gds.louvain.stream('social')
YIELD nodeId, communityId
RETURN gds.util.asNode(nodeId).name AS name, communityId
ORDER BY communityId
图算法
Neo4j提供丰富的图算法库,包括中心性、社区发现、路径查找等。
@Service
public class GraphAlgorithmService {
@Autowired
private Driver driver;
// PageRank算法
public List<Map<String, Object>> pageRank() {
try (Session session = driver.session()) {
return session.run(
"CALL gds.pageRank.stream('social') " +
"YIELD nodeId, score " +
"RETURN gds.util.asNode(nodeId).name AS name, score " +
"ORDER BY score DESC LIMIT 10"
).list(record -> Map.of(
"name", record.get("name").asString(),
"score", record.get("score").asDouble()
));
}
}
}
知识图谱应用
构建知识图谱实现智能问答、推荐系统和风控分析。
@Service
public class KnowledgeGraphService {
public List<String> findRelatedEntities(String entity) {
try (Session session = driver.session()) {
return session.run(
"MATCH (e:Entity {name: $entity})-[r]-(related) " +
"RETURN type(r) AS relation, labels(related)[0] AS type, related.name AS name",
Parameters.parameters("entity", entity)
).list(record -> String.format("%s --[%s]--> %s(%s)",
entity,
record.get("relation").asString(),
record.get("name").asString(),
record.get("type").asString()
));
}
}
}