Neo4j-05-图数据库 neo4j 实战
2018年1月8日大约 12 分钟
整体效果概览
Neo4j Graph VisualizationCreated using Neo4j (http://www.neo4j.com/)METHOD_CALLSMETHOD_CALLSMETHOD_CALLSMETHOD_CALLSMETHOD_CALLSMETHOD_CALLSMETHOD_CALLSBELO…BELONG_APPBELONG_APPBELONG_APPBELONG_APP appC,m… appD,m… appD,m… appA,m… appB,m… appB appD appC appA
核心实体定义
ChainMethod-接口方法
@NodeEntity(label = "ChainMethod")
@Data
public class Neo4jChainMethodEntity implements Serializable {
/**
* appName + methodName
*
* 测试下来有一个非常神奇的问题:如果一个属性以 xxxId 结尾,似乎会导致节点显示为空。
*/
@Id
private String methodFullName;
@Property
private String methodName;
/**
* @see com.github.houbb.method.chain.neo4j.constant.MethodTypeEnum
*/
@Property
private String methodType;
@Property
private String appName;
@Relationship(type = RelationshipTypeConst.BELONG_APP, direction = Relationship.OUTGOING)
private Neo4jChainAppEntity chainApp;
public Neo4jChainMethodEntity(String methodName, String methodType, String appName) {
this.methodName = methodName;
this.methodType = methodType;
this.appName = appName;
this.methodFullName = InnerAppMethodUtil.buildFullName(appName, methodName);
this.chainApp = new Neo4jChainAppEntity(appName);
}
}
ChainApp-应用
@NodeEntity(label = "ChainApp")
@Data
public class Neo4jChainAppEntity implements Serializable {
@Id
private String appName;
public Neo4jChainAppEntity(String appName) {
this.appName = appName;
}
}
关系
/**
* method 方法名称
*/
@RelationshipEntity(type = RelationshipTypeConst.METHOD_CALLS)
@Data
public class Neo4jChainMethodRelationshipEntity implements Serializable {
/**
* 当前调用关系的唯一标识
*
* 如何保证唯一呢?
*
* md5(tid+startMethod+endMethod)?
*/
@Id
private String methodRelationId;
/**
* 链路唯一标识 traceId
*/
@Index
@Property
private String tid;
/**
* 链路哈希
*/
@Property
@Index
private String chainHash;
/**
* 开始节点
*/
@StartNode
private Neo4jChainMethodEntity startMethod;
/**
* 结束节点
*/
@EndNode
private Neo4jChainMethodEntity endMethod;
public Neo4jChainMethodRelationshipEntity(String tid, Neo4jChainMethodEntity startMethod, Neo4jChainMethodEntity endMethod) {
this.tid = tid;
this.startMethod = startMethod;
this.endMethod = endMethod;
}
}
链路初始化
初始化
/**
* 数据初始化
*
* methodA1 -WEB
* methodB1 -DUBBO
* methodC1 -DUBBO
* methodD1 -DUBBO
*/
@Test
public void initMethodRelationshipTest() {
Neo4jChainMethodEntity methodA1 = new Neo4jChainMethodEntity("methodA1", MethodTypeEnum.WEB.getCode(),
"appA");
Neo4jChainMethodEntity methodB1 = new Neo4jChainMethodEntity("methodB1", MethodTypeEnum.DUBBO.getCode(),
"appB");
Neo4jChainMethodEntity methodC1 = new Neo4jChainMethodEntity("methodC1", MethodTypeEnum.DUBBO.getCode(),
"appC");
Neo4jChainMethodEntity methodD1 = new Neo4jChainMethodEntity("methodD1", MethodTypeEnum.DUBBO.getCode(),
"appD");
Neo4jChainMethodEntity methodD2 = new Neo4jChainMethodEntity("methodD2", MethodTypeEnum.SERVICE.getCode(),
"appD");
// 保存方法信息
chainMethodRepository.save(methodA1);
chainMethodRepository.save(methodB1);
chainMethodRepository.save(methodC1);
chainMethodRepository.save(methodD1);
chainMethodRepository.save(methodD2);
// 第一个调用链路
final String tidFirst = "T0001";
//A=>B
Neo4jChainMethodRelationshipEntity relationshipFirstA = new Neo4jChainMethodRelationshipEntity(tidFirst, methodA1, methodB1);
//A=>C
Neo4jChainMethodRelationshipEntity relationshipFirstB = new Neo4jChainMethodRelationshipEntity(tidFirst, methodA1, methodC1);
//B=>D
Neo4jChainMethodRelationshipEntity relationshipFirstC = new Neo4jChainMethodRelationshipEntity(tidFirst, methodB1, methodD1);
List chainListFirst = Arrays.asList(relationshipFirstA, relationshipFirstB, relationshipFirstC);
chainMethodRelationshipService.batchAdd(chainListFirst);
// 第二个调用链路
final String tidSecond = "T0002";
//A=>B
Neo4jChainMethodRelationshipEntity relationshipSecondA = new Neo4jChainMethodRelationshipEntity(tidSecond, methodA1, methodB1);
//A=>C
Neo4jChainMethodRelationshipEntity relationshipSecondB = new Neo4jChainMethodRelationshipEntity(tidSecond, methodA1, methodC1);
//C=>D
Neo4jChainMethodRelationshipEntity relationshipSecondC = new Neo4jChainMethodRelationshipEntity(tidSecond, methodC1, methodD1);
//D1=>D2
Neo4jChainMethodRelationshipEntity relationshipSecondD = new Neo4jChainMethodRelationshipEntity(tidSecond, methodD1, methodD2);
List chainListSecond = Arrays.asList(relationshipSecondA, relationshipSecondB, relationshipSecondC, relationshipSecondD);
chainMethodRelationshipService.batchAdd(chainListSecond);
}
对应的链路效果
Neo4j Graph VisualizationCreated using Neo4j (http://www.neo4j.com/)CHAIN_CALLSCHAIN_CALLSCHAIN_CALLSCHAIN_CALLSCHAIN_CALLSCHAIN_CALLSCHAIN_CALLS appA,m… appC,m… appB,m… appD,m… appD,m… appD,m… appA,m… appC,m… appB,m…
清空
MATCH (n)
DETACH DELETE n;
查询
作为入口:
match p=(startM)-[r:METHOD_CALLS]->(endM)
where (r.endMethodFullName='appD,methodD1')
return startM, r, endM
作为出口:
match p=(startM)-[r:METHOD_CALLS]->(endM)
where (r.startMethodFullName='appD,methodD1')
return startM, r, endM
必须要有方向性。
match p=(startM)-[r:METHOD_CALLS]->(endM)
where (r.startMethodFullName='appD,methodD1')
return r
过滤
MATCH p=(startM)-[r:METHOD_CALLS]->(endM)
where r.tid='T0001'
RETURN startM, r, endM
LIMIT 1000
根据节点直接查询
neo4j 如何查询一个节点关联的所有边信息
MATCH (n)-[r]-(m)
WHERE n.methodFullName = 'appB,methodB1'
RETURN r
neo4j 如何查询一个节点所有 income 进入边的信息,且 这个边的类别是 METHOD_CALLS
要查询一个节点所有入边的信息,且这些边的类别是METHOD_CALLS
,你可以使用Cypher查询语言。以下是如何查询一个节点所有METHOD_CALLS
类别的入边的示例:
假设你有一个节点,它的ID为node_id
,你想查询所有指向这个节点的METHOD_CALLS
类别的入边。你可以使用以下Cypher查询:
MATCH (n)(m)
WHERE n.methodFullName = 'appB,methodB1'
RETURN n,r,m
LIMIT 1000
小结
基本的关系创建实例。
参考资料
贡献者
binbin.hou