[英]Selecting all connected nodes in a sub-graph with a specific starting point to display in an R visualization
我有一个用于社交网络分析的简单neo4j数据库。 该数据库由用户节点和用户可能共有的其他节点(例如电话或地址)组成。 关系只有一种类型:[:HAS]。 为了使一个用户与另一个用户匹配,他们必须遍历它们之间的至少一个节点。
我们的目标是将这些数据存储在图形中,并部署R Shiny应用程序以输入用户ID并查看已连接用户的完整网络。 为了做到这一点,我们需要从连接的子图中将所有节点和关系拉到边缘数据帧中。
通过使用以下密码查询,我们已经取得了一些成功。 但是,此查询将仅拉出最多5个连接度的节点。 对于任何高度连接的节点,它也会失败-在此过程中冻结了neo4j实例。 我们应该使用一种更有效的方法将图形数据转换为边缘数据帧吗?
edges_query=paste('MATCH (c0:user {userID:',as.character(cust_id),'})-[]->(l1)
OPTIONAL MATCH (l1)<-[]-(c1)
where id(c1) <> id(c0)
OPTIONAL MATCH (c1)-[]->(l2)
where id(l2) <> id(l1)
OPTIONAL MATCH (l2)<-[]-(c2)
where id(c2) <> id(c0)
OPTIONAL MATCH (c2)-[]->(l3)
where id(l3) <> id(l2)
OPTIONAL MATCH (l3)<-[]-(c3)
where id(c3) <> id(c2)
OPTIONAL MATCH (c3)-[]->(l4)
where id(l4) <> id(l3)
OPTIONAL MATCH (l4)<-[]-(c4)
where id(c4) <> id(c3)
OPTIONAL MATCH (c4)-[]->(l5)
where id(l5) <> id(l4)
OPTIONAL MATCH (l5)<-[]-(c5)
where id(c5) <> id(c4)
return
ID(c0) as c0_node_id
, c0.userID as c0_user_id
, ID(l1) as l1_node_id
, LABELS(l1) as l1_node_type
, ID(c1) as c1_node_id
, c1.userID as c1_user_id
, id(l2) as l2_node_id
, labels(l2) as l2_node_type
, ID(c2) as c2_node_id
, c2.userID as c2_user_id
, id(l3) as l3_node_id
, labels(l3) as l3_node_type
, ID(c3) as c3_node_id
, c3.userID as c3_user_id
, id(l4) as l4_node_id
, labels(l4) as l4_node_type
, ID(c4) as c4_node_id
, c4.userID as c4_user_id
, id(l5) as l5_node_id
, labels(l5) as l5_node_type
, ID(c5) as c5_node_id
, c5.userID as c5_user_id
',sep='')
您应该在Cypher中使用可变长度路径匹配语法。 该语法为[:REL_TYPE*min..max]
,例如[:HAS*..5]
,其中默认min
为1。
您还应该使用参数而不是构建字符串。 在运行cypher
函数时,例如在查询中使用命名参数并将其替换为其值,而不是使用paste
来嵌入cust_id
。
cypher(graph, "MATCH (n:User {userID: {cust_id} }) RETURN n.userID", cust_id=12345)
让我为您展示一个示例图形示例。
library(RNeo4j)
library(visNetwork)
vis = function(edges) {
nodes = data.frame(id=unique(c(edges$from, edges$to)))
nodes$label = nodes$id
visNetwork(nodes, edges)
}
graph = startGraph("http://localhost:7474/db/data")
query = "
MATCH p = (:User {userID: {cust_id}})-[:HAS*..5]-(:User)
WITH [x IN nodes(p) WHERE x:User] AS users
UNWIND range(1, size(users) - 1) AS idx
WITH users[idx - 1] AS from, users[idx] AS to
RETURN DISTINCT from.userID AS from, to.userID AS to;
"
edges = cypher(graph, query, cust_id="Tom Cruise")
vis(edges)
我编辑了Neo4j随附的电影图以适合您的模型。 上面的代码在RStudio中为我提供了以下内容:
然后,您可以在带有renderVisNetwork
的Shiny应用程序中轻松使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.