|
|
package com.supervision.neo4j.service.impl;
|
|
|
|
|
|
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());
|
|
|
// 节点和关系合并
|
|
|
Map<String, NodeMapRecord> nodeRecordMap = electNodeRecord(distinctNodes);
|
|
|
list = mergerWebRel(list, nodeRecordMap);
|
|
|
nodes = mergeNode(nodes, nodeRecordMap);
|
|
|
|
|
|
map.put("list", list);
|
|
|
map.put("nodes", nodes);
|
|
|
return R.ok(map);
|
|
|
}
|
|
|
|
|
|
@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);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|