package com.supervision.neo4j.service.impl ;
import cn.hutool.core.lang.Pair ;
import cn.hutool.core.util.StrUtil ;
import cn.hutool.poi.excel.ExcelReader ;
import cn.hutool.poi.excel.ExcelUtil ;
import com.supervision.common.domain.R ;
import com.supervision.neo4j.domain.CaseNode ;
import com.supervision.neo4j.domain.Rel ;
import com.supervision.neo4j.dto.WebRelDTO ;
import com.supervision.neo4j.service.Neo4jService ;
import com.supervision.neo4j.utils.Neo4jUtils ;
import com.supervision.police.vo.GraphReqVO ;
import lombok.Data ;
import lombok.extern.slf4j.Slf4j ;
import org.apache.commons.lang3.StringUtils ;
import org.neo4j.driver.Record ;
import org.neo4j.driver.* ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Service ;
import java.util.* ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.function.Function ;
import java.util.function.Predicate ;
import java.util.stream.Collectors ;
/ * *
* @author qmy
* @since 2023 - 10 - 26
* /
@Slf4j
@Service
public class Neo4jServiceImpl implements Neo4jService {
private final Driver driver ;
@Autowired
private Neo4jServiceImpl ( Driver driver ) {
this . driver = driver ;
}
@Override
public CaseNode save ( CaseNode caseNode ) {
if ( StringUtils . isEmpty ( caseNode . getName ( ) ) | | StringUtils . isEmpty ( caseNode . getNodeType ( ) ) ) {
throw new RuntimeException ( "未传节点名称或节点类型或图谱类型!" ) ;
}
List < CaseNode > byName = findByName ( caseNode . getCaseId ( ) , caseNode . getRecordId ( ) , caseNode . getNodeType ( ) , caseNode . getName ( ) , caseNode . getPicType ( ) ) ;
if ( byName ! = null & & ! byName . isEmpty ( ) ) {
throw new RuntimeException ( "名称已存在!" ) ;
}
CaseNode res = null ;
try {
Session session = driver . session ( ) ;
StringBuilder cql = new StringBuilder ( ) ;
Map < String , Object > params = new HashMap < > ( ) ;
cql . append ( "CREATE (n:" ) . append ( caseNode . getNodeType ( ) ) . append ( "{name:$name" ) ;
params . put ( "name" , caseNode . getName ( ) ) ;
if ( StringUtils . isNotEmpty ( caseNode . getRecordId ( ) ) ) {
cql . append ( ", recordSplitId:$recordSplitId" ) ;
params . put ( "recordSplitId" , caseNode . getRecordSplitId ( ) ) ;
}
if ( StringUtils . isNotEmpty ( caseNode . getRecordId ( ) ) ) {
cql . append ( ", recordId:$recordId" ) ;
params . put ( "recordId" , caseNode . getRecordId ( ) ) ;
}
if ( StringUtils . isNotEmpty ( caseNode . getCaseId ( ) ) ) {
cql . append ( ", caseId:$caseId" ) ;
params . put ( "caseId" , caseNode . getCaseId ( ) ) ;
}
if ( StringUtils . isNotEmpty ( caseNode . getPicType ( ) ) ) {
cql . append ( ", picType:$picType" ) ;
params . put ( "picType" , caseNode . getPicType ( ) ) ;
}
cql . append ( "})" ) . append ( Neo4jUtils . NODE_RETURN ) ;
Result run = session . run ( cql . toString ( ) , params ) ;
res = Neo4jUtils . getOneNode ( run ) ;
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
return res ;
}
/ * *
* 删 除 节 点 , 注 意 , 删 除 节 点 的 时 候 , 要 先 把 边 删 除 掉 , 不 然 会 报 错
*
* @param id 点 的 ID
* /
@Override
public void delNode ( Long id ) {
try {
Session session = driver . session ( ) ;
StringBuilder cql = new StringBuilder ( ) ;
cql . append ( "MATCH (n) where id(n) = " ) . append ( id ) . append ( " DELETE n" ) ;
log . info ( cql . toString ( ) ) ;
Result run = session . run ( cql . toString ( ) ) ;
while ( run . hasNext ( ) ) {
run . next ( ) ;
}
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
}
@Override
public void deleteNoRelationNode ( Long id ) {
try {
Session session = driver . session ( ) ;
StringBuilder cql = new StringBuilder ( ) ;
cql . append ( "MATCH (n) WHERE n.id = " ) . append ( id ) . append ( " AND NOT (n)--() DELETE n" ) ;
log . info ( cql . toString ( ) ) ;
Result run = session . run ( cql . toString ( ) ) ;
while ( run . hasNext ( ) ) {
run . next ( ) ;
}
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
}
/ * *
* 删 除 边
*
* @param relId 边 ID
* /
public void deleteRel ( Long relId ) {
try {
Session session = driver . session ( ) ;
StringBuilder cql = new StringBuilder ( ) ;
cql . append ( "MATCH ()-[r]->() WHERE id(r) = " ) . append ( relId ) . append ( " DELETE r" ) ;
log . info ( cql . toString ( ) ) ;
Result run = session . run ( cql . toString ( ) ) ;
while ( run . hasNext ( ) ) {
run . next ( ) ;
}
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
}
@Override
public CaseNode findById ( Long id ) {
CaseNode node = null ;
try {
Session session = driver . session ( ) ;
Result run = session . run ( "MATCH (n) where id(n) = " + id + Neo4jUtils . NODE_RETURN ) ;
node = Neo4jUtils . getOneNode ( run ) ;
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
return node ;
}
@Override
public List < CaseNode > findByName ( String caseId , String recordId , String nodeType , String name , String picType ) {
List < CaseNode > list = new ArrayList < > ( ) ;
try {
Session session = driver . session ( ) ;
StringBuilder cql = new StringBuilder ( ) ;
cql . append ( "MATCH (n" ) ;
if ( StringUtils . isNotEmpty ( nodeType ) ) {
cql . append ( ":" ) ;
cql . append ( nodeType ) ;
}
cql . append ( ") where 1 = 1" ) ;
if ( StringUtils . isNotEmpty ( caseId ) ) {
cql . append ( " and n.caseId = " ) ;
cql . append ( caseId ) ;
}
if ( StringUtils . isNotEmpty ( recordId ) ) {
cql . append ( " and n.recordId = " ) ;
cql . append ( recordId ) ;
}
if ( StringUtils . isNotEmpty ( name ) ) {
cql . append ( " and n.name = '" ) ;
cql . append ( name ) ;
cql . append ( "'" ) ;
}
if ( StringUtils . isNotEmpty ( picType ) ) {
cql . append ( " and n.picType = " ) ;
cql . append ( picType ) ;
}
cql . append ( Neo4jUtils . NODE_RETURN ) ;
Result run = session . run ( cql . toString ( ) ) ;
list = Neo4jUtils . getNodeList ( run ) ;
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
return list ;
}
@Override
public CaseNode findOneByName ( String caseId , String recordId , String nodeType , String name , String picType ) {
CaseNode node = null ;
try {
Session session = driver . session ( ) ;
StringBuilder cql = new StringBuilder ( ) ;
Map < String , Object > params = new HashMap < > ( ) ;
cql . append ( "MATCH (n" ) ;
if ( StringUtils . isNotEmpty ( nodeType ) ) {
cql . append ( ":" ) ;
cql . append ( nodeType ) ;
}
cql . append ( ") where 1 = 1" ) ;
if ( StringUtils . isNotEmpty ( caseId ) ) {
cql . append ( " and n.caseId = $caseId" ) ;
params . put ( "caseId" , caseId ) ;
}
if ( StringUtils . isNotEmpty ( recordId ) ) {
cql . append ( " and n.recordId = $recordId" ) ;
params . put ( "recordId" , recordId ) ;
}
if ( StringUtils . isNotEmpty ( name ) ) {
cql . append ( " and n.name = $name" ) ;
params . put ( "name" , name ) ;
}
if ( StringUtils . isNotEmpty ( picType ) ) {
cql . append ( " and n.picType = $picType" ) ;
params . put ( "picType" , picType ) ;
}
cql . append ( Neo4jUtils . NODE_RETURN ) ;
Result run = session . run ( cql . toString ( ) , params ) ;
node = Neo4jUtils . getOneNode ( run ) ;
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
return node ;
}
@Override
public Rel findRelation ( Rel rel ) {
try {
Session session = driver . session ( ) ;
Map < String , Object > params = new HashMap < > ( ) ;
String cql = "MATCH (a)-[rel:" + rel . getName ( ) + "]->(b) where id(a) = $sourceId and id(b) = $targetId" +
Neo4jUtils . REL_RETURN ;
params . put ( "sourceId" , rel . getSourceId ( ) ) ;
params . put ( "targetId" , rel . getTargetId ( ) ) ;
Result run = session . run ( cql , params ) ;
rel = Neo4jUtils . getOneRel ( run ) ;
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
if ( rel ! = null & & rel . getId ( ) ! = null ) {
return rel ;
} else {
return null ;
}
}
@Override
public Rel saveRelation ( Rel rel ) {
try {
Session session = driver . session ( ) ;
Map < String , Object > params = new HashMap < > ( ) ;
String cql = "MATCH (a), (b) where id(a) = $sourceId and id(b) = $targetId CREATE(a)-[rel:" + rel . getName ( ) +
"]->(b) " + Neo4jUtils . REL_RETURN ;
params . put ( "sourceId" , rel . getSourceId ( ) ) ;
params . put ( "targetId" , rel . getTargetId ( ) ) ;
Result run = session . run ( cql , params ) ;
rel = Neo4jUtils . getOneRel ( run ) ;
} catch ( Exception e ) {
log . error ( e . getMessage ( ) , e ) ;
}
return rel ;
}
@Override
public R < ? > getCaseGraph ( GraphReqVO graphReqVO ) {
Map < String , Object > map = new HashMap < > ( ) ;
List < WebRelDTO > list = new ArrayList < > ( ) ;
List < Map < String , String > > nodes = new ArrayList < > ( ) ;
try {
Session session = driver . session ( ) ;
StringBuilder relQuery = new StringBuilder ( "MATCH (n)-[rel]->(m) " +
"WHERE n.picType = $picType " +
"AND n.caseId = $caseId " ) ;
Map < String , Object > params = new HashMap < > ( ) ;
params . put ( "picType" , graphReqVO . getPicType ( ) ) ;
params . put ( "caseId" , graphReqVO . getCaseId ( ) ) ;
if ( StringUtils . isNotEmpty ( graphReqVO . getQueryStr ( ) ) ) {
params . put ( "queryStr" , graphReqVO . getQueryStr ( ) ) ;
relQuery . append ( "AND (n.name CONTAINS $queryStr OR type(rel) CONTAINS $queryStr OR m.name CONTAINS $queryStr) " ) ;
}
if ( graphReqVO . getNodeLabels ( ) ! = null & & ! graphReqVO . getNodeLabels ( ) . isEmpty ( ) ) {
params . put ( "nodeLabels" , graphReqVO . getNodeLabels ( ) ) ;
relQuery . append ( "AND (ANY(label IN $nodeLabels WHERE label IN labels(n)) " +
"OR ANY(label IN $nodeLabels WHERE label IN labels(m))) " ) ;
}
if ( graphReqVO . getRelTypes ( ) ! = null & & ! graphReqVO . getRelTypes ( ) . isEmpty ( ) ) {
params . put ( "relTypes" , graphReqVO . getRelTypes ( ) ) ;
relQuery . append ( "AND ANY(type IN $relTypes WHERE type = type(rel)) " ) ;
}
relQuery . append ( "RETURN id(rel) as id, n.name as source, id(n) as sourceId, n.name as sourceName, type(rel) as relName, m.name as target, id(m) as targetId, m.name as targetName" ) ;
log . info ( "relQuery:{}" , relQuery ) ;
Result run = session . run ( relQuery . toString ( ) , params ) ;
while ( run . hasNext ( ) ) {
Record record = run . next ( ) ;
// 组织边
long sourceId = record . get ( "sourceId" ) . asLong ( ) ;
String relName = record . get ( "relName" ) . asString ( ) ;
long targetId = record . get ( "targetId" ) . asLong ( ) ;
list . add ( new WebRelDTO ( sourceId , targetId , relName ) ) ;
// 组织节点
Map < String , String > sourceNodeMap = new HashMap < > ( ) ;
sourceNodeMap . put ( "name" , record . get ( "sourceName" ) . asString ( ) ) ;
sourceNodeMap . put ( "id" , String . valueOf ( sourceId ) ) ;
nodes . add ( sourceNodeMap ) ;
Map < String , String > targetNodeMap = new HashMap < > ( ) ;
targetNodeMap . put ( "name" , record . get ( "targetName" ) . asString ( ) ) ;
targetNodeMap . put ( "id" , String . valueOf ( targetId ) ) ;
nodes . add ( targetNodeMap ) ;
}
} catch ( Exception e ) {
log . error ( "查询失败" , e ) ;
}
// 根据节点ID去重
List < Map < String , String > > distinctNodes = new ArrayList < > ( nodes . stream ( )
. collect ( Collectors . toMap (
node - > node . get ( "id" ) , // 以 ID 为唯一键
node - > node , // 保留整个 Map 作为值
( existing , replacement ) - > existing ) ) // 如果有重复 ID, 保留第一个
. values ( ) ) ;
// 节点和关系合并
Pair < List < WebRelDTO > , List < Map < String , String > > > pair = mergeRecord ( distinctNodes , list ) ;
map . put ( "list" , pair . getKey ( ) ) ;
map . put ( "nodes" , pair . getValue ( ) ) ;
return R . ok ( map ) ;
}
public Pair < List < WebRelDTO > , List < Map < String , String > > > mergeRecord ( List < Map < String , String > > nodes , List < WebRelDTO > relDTOS ) {
Map < String , NodeMapRecord > nodeRecordMap = electNodeRecord ( nodes ) ;
return Pair . of ( mergerWebRel ( relDTOS , nodeRecordMap ) , mergeNode ( nodes , nodeRecordMap ) ) ;
}
@Override
public R < ? > getNodeAndRelationListByCaseId ( String picType , String caseId ) {
Map < String , Set < String > > map = new HashMap < > ( ) ;
Set < String > nodeLabels = new HashSet < > ( ) ;
Set < String > relTypes = new HashSet < > ( ) ;
try ( Session session = driver . session ( ) ) {
// 查询所有匹配caseId的节点及其关联关系
String query = "MATCH (n)-[r]->(m) WHERE n.caseId = $caseId AND m.caseId = $caseId RETURN labels(n) as sourceLabels, type(r) as relName, labels(m) as targetLabels" ;
session . executeRead ( tx - > {
Result result = tx . run ( query , Values . parameters ( "caseId" , caseId ) ) ;
while ( result . hasNext ( ) ) {
Record record = result . next ( ) ;
List < String > sourceLabels = record . get ( "sourceLabels" ) . asList ( Value : : asString ) ;
List < String > targetLabels = record . get ( "targetLabels" ) . asList ( Value : : asString ) ;
if ( ! sourceLabels . isEmpty ( ) ) {
nodeLabels . add ( sourceLabels . get ( 0 ) ) ;
}
if ( ! targetLabels . isEmpty ( ) ) {
nodeLabels . add ( targetLabels . get ( 0 ) ) ;
}
relTypes . add ( record . get ( "relName" ) . asString ( ) ) ;
}
return null ;
} ) ;
} catch ( Exception e ) {
log . error ( "查询失败" , e ) ;
}
log . info ( "查询到的节点类型{}个:{}" , nodeLabels . size ( ) , nodeLabels ) ;
log . info ( "查询到的关系类型{}个:{}" , relTypes . size ( ) , relTypes ) ;
map . put ( "nodeLabels" , nodeLabels ) ;
map . put ( "relTypes" , relTypes ) ;
return R . ok ( map ) ;
}
record NodeMapRecord ( String name , String id , Set < String > idSet ) {
}
/ * *
* 推 选 出 代 表 节 点 信 息
*
* @param nodes key : name , entityName , id 节 点 信 息
* @return key : name , value : NodeMapRecord
* /
private Map < String , NodeMapRecord > electNodeRecord ( List < Map < String , String > > nodes ) {
Map < String , NodeMapRecord > nodeRecordMap = new HashMap < > ( ) ;
for ( Map < String , String > node : nodes ) {
String name = node . get ( "name" ) ;
String id = node . get ( "id" ) ;
NodeMapRecord nodeMapRecord = nodeRecordMap . get ( name ) ;
if ( nodeMapRecord = = null ) {
Set < String > idSet = new HashSet < > ( ) ;
idSet . add ( id ) ;
nodeRecordMap . put ( name , new NodeMapRecord ( name , id , idSet ) ) ;
} else {
nodeMapRecord . idSet . add ( id ) ;
}
}
return nodeRecordMap ;
}
/ * *
* 合 并 节 点 信 息
* 合 并 依 据 :
* name 为 唯 一 标 识
*
* @param nodes key : name , entityName , id
* @param nodeRecordMap 代 表 节 点 信 息
* @return 合 并 后 的 节 点 信 息
* /
private List < Map < String , String > > mergeNode ( List < Map < String , String > > nodes , Map < String , NodeMapRecord > nodeRecordMap ) {
return nodes . stream ( ) . map ( map - > {
Map < String , String > nodeMap = new HashMap < > ( ) ;
nodeMap . put ( "name" , map . get ( "name" ) ) ;
NodeMapRecord nodeMapRecord = nodeRecordMap . get ( map . get ( "name" ) ) ;
if ( null = = nodeMapRecord ) {
log . warn ( "mergeNode:节点信息异常, nodeRecordMap中不存在节点名称为: {}的NodeMapRecord" , map . get ( "name" ) ) ;
return nodeMap ;
}
if ( ! nodeMapRecord . idSet . contains ( map . get ( "id" ) ) ) {
log . warn ( "mergeNode:节点信息异常, nodeMapRecord.idSet中不包含节点id:{},节点名称为:{}" , map . get ( "id" ) , map . get ( "name" ) ) ;
return nodeMap ;
}
nodeMap . put ( "id" , nodeMapRecord . id ) ;
return nodeMap ;
} ) . filter ( map - > StrUtil . isNotEmpty ( map . get ( "id" ) ) )
. filter ( distinctPredicate ( m - > m . get ( "id" ) ) ) . collect ( Collectors . toList ( ) ) ;
}
/ * *
* 合 并 关 系 信 息
*
* @param webRelDTOList 关 系 信 息
* @param nodeRecordMap 代 表 节 点 信 息
* @return 合 并 后 的 关 系 信 息
* /
private List < WebRelDTO > mergerWebRel ( List < WebRelDTO > webRelDTOList , Map < String , NodeMapRecord > nodeRecordMap ) {
Map < String , NodeMapRecord > idNodeRecordMap = nodeRecordMap . entrySet ( ) . stream ( )
. collect ( Collectors . toMap ( entry - > entry . getValue ( ) . id , Map . Entry : : getValue ) ) ;
return webRelDTOList . stream ( ) . map ( webRelDTO - > {
String target = webRelDTO . getTarget ( ) ;
String source = webRelDTO . getSource ( ) ;
String name = webRelDTO . getName ( ) ;
String sourceNew = idNodeRecordMap . entrySet ( ) . stream ( )
. filter ( entry - > entry . getValue ( ) . idSet . contains ( source ) )
. findAny ( ) . map ( Map . Entry : : getKey ) . orElse ( "" ) ;
String targetNew = idNodeRecordMap . entrySet ( ) . stream ( )
. filter ( entry - > entry . getValue ( ) . idSet . contains ( target ) )
. findAny ( ) . map ( Map . Entry : : getKey ) . orElse ( "" ) ;
if ( StrUtil . isEmpty ( sourceNew ) | | StrUtil . isEmpty ( targetNew ) ) {
log . warn ( "mergerWebRel:关系信息异常, nodeRecordMap中不存在节点id:{}或节点id:{}信息,节点名称为:{}" , source , target , name ) ;
}
return new WebRelDTO ( sourceNew , targetNew , name ) ;
} ) . filter ( webRelDTO - > StrUtil . isNotEmpty ( webRelDTO . getSource ( ) ) & & StrUtil . isNotEmpty ( webRelDTO . getTarget ( ) ) )
. filter ( distinctPredicate ( rel - > rel . getSource ( ) + rel . getTarget ( ) ) ) . toList ( ) ;
}
private < K > Predicate < K > distinctPredicate ( Function < K , Object > function ) {
ConcurrentHashMap < Object , Boolean > map = new ConcurrentHashMap < > ( ) ;
return ( t ) - > null = = map . putIfAbsent ( function . apply ( t ) , true ) ;
}
@Override
public void createAbstractGraph ( String path , String sheetName ) {
// 首先从数据库中读到数据
ExcelReader reader = ExcelUtil . getReader ( path , sheetName ) ;
List < AbstractGraphExcelHeader > abstractGraphExcelHeaders = reader . readAll ( AbstractGraphExcelHeader . class ) ;
Map < String , CaseNode > nodeMap = new HashMap < > ( ) ;
Map < String , Rel > relMap = new HashMap < > ( ) ;
for ( AbstractGraphExcelHeader abstractGraphExcelHeader : abstractGraphExcelHeaders ) {
// from
if ( ! nodeMap . containsKey ( abstractGraphExcelHeader . getFrom ( ) ) ) {
CaseNode caseNode = new CaseNode ( abstractGraphExcelHeader . getFrom ( ) , abstractGraphExcelHeader . getFrom ( ) , "0" ) ;
log . info ( "点:{}插入成功" , abstractGraphExcelHeader . getFrom ( ) ) ;
CaseNode save = save ( caseNode ) ;
nodeMap . put ( abstractGraphExcelHeader . getFrom ( ) , save ) ;
}
// to
if ( ! nodeMap . containsKey ( abstractGraphExcelHeader . getTo ( ) ) ) {
CaseNode caseNode = new CaseNode ( abstractGraphExcelHeader . getTo ( ) , abstractGraphExcelHeader . getTo ( ) , "0" ) ;
CaseNode save = save ( caseNode ) ;
log . info ( "点:{}插入成功" , abstractGraphExcelHeader . getTo ( ) ) ;
nodeMap . put ( abstractGraphExcelHeader . getTo ( ) , save ) ;
}
// relation
if ( ! relMap . containsKey ( abstractGraphExcelHeader . getFrom ( ) + "->" + abstractGraphExcelHeader . getRelation ( ) + "->" + abstractGraphExcelHeader . getTo ( ) ) ) {
Rel rel = new Rel ( nodeMap . get ( abstractGraphExcelHeader . getFrom ( ) ) . getId ( ) , abstractGraphExcelHeader . getRelation ( ) , nodeMap . get ( abstractGraphExcelHeader . getTo ( ) ) . getId ( ) , "0" ) ;
saveRelation ( rel ) ;
log . info ( "关系:{}插入成功" , ( abstractGraphExcelHeader . getFrom ( ) + "->" + abstractGraphExcelHeader . getRelation ( ) + "->" + abstractGraphExcelHeader . getTo ( ) ) ) ;
relMap . put ( abstractGraphExcelHeader . getFrom ( ) + "->" + abstractGraphExcelHeader . getRelation ( ) + "->" + abstractGraphExcelHeader . getTo ( ) , rel ) ;
}
}
}
public void deleteAbstractGraph ( ) {
Session session = driver . session ( ) ;
// 首先查出来所有的抽象节点
Result run = session . run ( "MATCH (n) WHERE n.picType = '0' OPTIONAL MATCH (n)-[r]-() RETURN id(n) as nodeId, id(r) as relId" ) ;
Set < String > nodeIdSet = new HashSet < > ( ) ;
HashSet < String > relIdSet = new HashSet < > ( ) ;
while ( run . hasNext ( ) ) {
Record record = run . next ( ) ;
String nodeId = Neo4jUtils . valueTransportString ( record . get ( "nodeId" ) ) ;
nodeIdSet . add ( nodeId ) ;
String relId = Neo4jUtils . valueTransportString ( record . get ( "relId" ) ) ;
relIdSet . add ( relId ) ;
}
// 删除边
for ( String s : relIdSet ) {
long relId = Long . parseLong ( s ) ;
deleteRel ( relId ) ;
log . info ( "删除边:{} 成功" , relId ) ;
}
// 删除节点
for ( String s : nodeIdSet ) {
long nodeId = Long . parseLong ( s ) ;
delNode ( nodeId ) ;
log . info ( "删除节点:{} 成功" , nodeId ) ;
}
}
@Data
private static class AbstractGraphExcelHeader {
private String from ;
private String relation ;
private String to ;
}
@Data
private static class MockDataGraphExcelHeader {
private String fromType ;
private String from ;
private String relation ;
private String to ;
private String toType ;
}
@Override
public void mockTestGraph ( String path , String sheetName , String recordId , String recordSplitId , String caseId ) {
// 首先从数据库中读到数据
ExcelReader reader = ExcelUtil . getReader ( path , sheetName ) ;
List < MockDataGraphExcelHeader > mockDataGraphExcelList = reader . readAll ( MockDataGraphExcelHeader . class ) ;
Map < String , CaseNode > nodeMap = new HashMap < > ( ) ;
Map < String , Rel > relMap = new HashMap < > ( ) ;
for ( MockDataGraphExcelHeader mockData : mockDataGraphExcelList ) {
// from
if ( ! nodeMap . containsKey ( mockData . getFrom ( ) ) ) {
CaseNode caseNode = new CaseNode ( mockData . getFrom ( ) , mockData . getFromType ( ) , recordSplitId , recordId , caseId , "1" ) ;
log . info ( "点:{}插入成功" , mockData . getFrom ( ) ) ;
CaseNode save = save ( caseNode ) ;
nodeMap . put ( mockData . getFrom ( ) , save ) ;
}
// to
if ( ! nodeMap . containsKey ( mockData . getTo ( ) ) ) {
CaseNode caseNode = new CaseNode ( mockData . getTo ( ) , mockData . getToType ( ) , recordSplitId , recordId , caseId , "1" ) ;
CaseNode save = save ( caseNode ) ;
log . info ( "点:{}插入成功" , mockData . getTo ( ) ) ;
nodeMap . put ( mockData . getTo ( ) , save ) ;
}
// relation
if ( ! relMap . containsKey ( mockData . getFrom ( ) + "->" + mockData . getRelation ( ) + "->" + mockData . getTo ( ) ) ) {
Rel rel = new Rel ( nodeMap . get ( mockData . getFrom ( ) ) . getId ( ) , mockData . getRelation ( ) , nodeMap . get ( mockData . getTo ( ) ) . getId ( ) , "1" ) ;
saveRelation ( rel ) ;
log . info ( "关系:{}插入成功" , ( mockData . getFrom ( ) + "->" + mockData . getRelation ( ) + "->" + mockData . getTo ( ) ) ) ;
relMap . put ( mockData . getFrom ( ) + "->" + mockData . getRelation ( ) + "->" + mockData . getTo ( ) , rel ) ;
}
}
}
@Override
public List < Record > executeCypher ( String cypher , Map < String , Object > parameters ) {
return this . driver . session ( ) . run ( cypher , parameters ) . list ( ) ;
}
}