@ -1,42 +1,47 @@
package com.supervision.neo4j.service.impl ;
import cn.hutool.core.collection.CollUtil ;
import cn.hutool.poi.excel.ExcelReader ;
import cn.hutool.poi.excel.ExcelUtil ;
import com.supervision.common.domain.R ;
import com.supervision.common.utils.StringUtils ;
import com.supervision.neo4j.domain.CaseNode ;
import com.supervision.neo4j.domain.Rel ;
import com.supervision.neo4j.service.Neo4jService ;
import com.supervision.neo4j.utils.Neo4jUtils ;
import lombok.Data ;
import lombok.extern.slf4j.Slf4j ;
import org.neo4j.cypherdsl.core.Case ;
import org.neo4j.driver.* ;
import org.neo4j.driver.Record ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Service ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.* ;
/ * *
* @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 R< ? > save( CaseNode caseNode ) {
public CaseNode save( CaseNode caseNode ) {
if ( StringUtils . isEmpty ( caseNode . getName ( ) ) | | StringUtils . isEmpty ( caseNode . getNodeType ( ) ) ) {
return R . fail ( "未传节点名称或节点类型或图谱类型!" ) ;
throw new RuntimeException ( "未传节点名称或节点类型或图谱类型!" ) ;
}
List < CaseNode > byName = findByName ( caseNode . getCaseId ( ) , caseNode . getRecordsId ( ) , caseNode . getNodeType ( ) , caseNode . getName ( ) , caseNode . getPicType ( ) ) ;
if ( byName ! = null & & ! byName . isEmpty ( ) ) {
return R . fail ( "名称已存在 ") ;
throw new RuntimeException ( "名称已存在! ") ;
}
CaseNode res = null ;
try {
@ -67,20 +72,50 @@ public class Neo4jServiceImpl implements Neo4jService {
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
return R. ok ( res) ;
return res;
}
/ * *
* 删 除 节 点 , 注 意 , 删 除 节 点 的 时 候 , 要 先 把 边 删 除 掉 , 不 然 会 报 错
*
* @param id 点 的 ID
* /
@Override
public R < ? > delNode ( Long id ) {
public void delNode( Long id ) {
try {
Session session = driver . session ( ) ;
StringBuffer cql = new StringBuffer ( ) ;
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 ( ) ) {
Record next = run . next ( ) ;
// log.info(next.toString());
}
} 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 ( ) ) {
Record next = run . next ( ) ;
// log.info(next.toString());
}
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
return R . ok ( ) ;
}
@Override
@ -267,13 +302,84 @@ public class Neo4jServiceImpl implements Neo4jService {
Result run = session . run ( "MATCH (m:LawActor), (n:FictionalOrgan) where m.name=$lawActor OPTIONAL MATCH (m)-[r:`冒充`]->(n) RETURN id(m) as startId, id(n) as endId, id(r) as relId, m.recordId as recordId, m.recordsId as recordsId" , params ) ;
while ( run . hasNext ( ) ) {
Record record = run . next ( ) ;
String id = record . get ( "startId" ) . asLong ( ) + "" ;
String endId = record . get ( "endId" ) . asLong ( ) + "" ;
String relId = record . get ( "relId" ) . asLong ( ) + "" ;
String id = Neo4jUtils . valueTransportString ( record . get ( "startId" ) ) ;
String endId = Neo4jUtils . valueTransportString ( record . get ( "endId" ) ) ;
String relId = Neo4jUtils . valueTransportString ( record . get ( "relId" ) ) ;
System . out . println ( "************" + id ) ;
System . out . println ( "************" + endId ) ;
System . out . println ( "************" + relId ) ;
}
return R . ok ( "222" ) ;
}
@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 ;
}
}