1. 添加图谱查询调试接口

topo_dev
xueqingkun 5 months ago
parent deb5e4f091
commit 15d90ec6e0

@ -3,8 +3,10 @@ package com.supervision.neo4j.service;
import com.supervision.common.domain.R;
import com.supervision.neo4j.domain.CaseNode;
import com.supervision.neo4j.domain.Rel;
import org.neo4j.driver.Record;
import java.util.List;
import java.util.Map;
/**
* @author qmy
@ -42,4 +44,6 @@ public interface Neo4jService {
void createAbstractGraph(String path, String sheetName);
void mockTestGraph(String path, String sheetName, String recordId, String recordSplitId,String caseId);
List<Record> executeCypher(String cypher, Map<String, Object> parameters);
}

@ -526,4 +526,9 @@ public class Neo4jServiceImpl implements Neo4jService {
}
}
}
@Override
public List<Record> executeCypher(String cypher,Map<String, Object> parameters) {
return this.driver.session().run(cypher, parameters).list();
}
}

@ -5,8 +5,10 @@ import com.supervision.police.domain.ModelAtomicIndex;
import com.supervision.police.domain.ModelIndex;
import com.supervision.police.dto.CaseAtomicIndexDTO;
import com.supervision.police.dto.CaseAtomicResultWrapper;
import com.supervision.police.vo.GraphDebugReqVO;
import com.supervision.police.dto.ValueCalculateScopeDTO;
import com.supervision.police.service.ModelIndexService;
import com.supervision.police.vo.GraphDebugResVO;
import com.supervision.police.vo.ModelIndexReqVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@ -140,5 +142,13 @@ public class ModelIndexController {
Map<String,List<ValueCalculateScopeDTO>> result = modelIndexService.listAtomicIndexAttributeScope(atomicIndexIds);
return R.ok(result);
}
@Operation(summary = "图谱推理调试")
@PostMapping("/atomic/debug/graph")
public R<GraphDebugResVO> graphDebug(@RequestBody GraphDebugReqVO graphDebugDTO) {
GraphDebugResVO result = modelIndexService.graphDebug(graphDebugDTO);
return R.ok(result);
}
}

@ -0,0 +1,30 @@
package com.supervision.police.dto.neo4j;
import lombok.Data;
import org.neo4j.driver.internal.InternalNode;
import java.util.Collection;
import java.util.Map;
@Data
public class NodeDTO {
private long id;
private String elementId;
private Map<String, Object> properties;
private Collection<String> labels;
public NodeDTO() {
}
public NodeDTO(InternalNode internalNode) {
this.id = internalNode.id();
this.elementId = internalNode.elementId();
this.properties = internalNode.asMap();
this.labels = internalNode.labels();
}
}

@ -0,0 +1,41 @@
package com.supervision.police.dto.neo4j;
import lombok.Data;
import org.neo4j.driver.internal.InternalNode;
import org.neo4j.driver.internal.InternalRelationship;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Path;
import org.neo4j.driver.types.Relationship;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Data
public class PathDTO {
private List<NodeDTO> nodes;
private List<RelationshipValueDTO> relationships;
public PathDTO() {
}
public PathDTO(Path path) {
Iterator<Node> nodeIterator = path.nodes().iterator();
List<NodeDTO> nodes = new ArrayList<>();
while (nodeIterator.hasNext()){
Node next = nodeIterator.next();
nodes.add(new NodeDTO((InternalNode) next));
}
this.nodes = nodes;
Iterator<Relationship> iterator = path.relationships().iterator();
List<RelationshipValueDTO> relationships = new ArrayList<>();
while (iterator.hasNext()){
relationships.add(new RelationshipValueDTO((InternalRelationship) iterator.next()));
}
this.relationships = relationships;
}
}

@ -0,0 +1,42 @@
package com.supervision.police.dto.neo4j;
import lombok.Data;
import org.neo4j.driver.internal.InternalRelationship;
import java.util.Map;
@Data
public class RelationshipValueDTO {
private long start;
private String startElementId;
private long end;
private String endElementId;
private String type;
private long id;
private String elementId;
private Map<String,Object> properties;
public RelationshipValueDTO() {
}
public RelationshipValueDTO(InternalRelationship relationship) {
this.start = (int) relationship.startNodeId();
this.startElementId = relationship.startNodeElementId();
this.end = relationship.endNodeId();
this.endElementId = relationship.endNodeElementId();
this.type = relationship.type();
this.id = relationship.id();
this.elementId = relationship.elementId();
this.properties = relationship.asMap();
}
}

@ -7,6 +7,8 @@ import com.supervision.police.domain.ModelIndex;
import com.supervision.police.dto.CaseAtomicIndexDTO;
import com.supervision.police.dto.CaseAtomicResultWrapper;
import com.supervision.police.dto.ValueCalculateScopeDTO;
import com.supervision.police.vo.GraphDebugReqVO;
import com.supervision.police.vo.GraphDebugResVO;
import com.supervision.police.vo.ModelIndexReqVO;
import java.util.List;
@ -55,5 +57,7 @@ public interface ModelIndexService extends IService<ModelIndex> {
boolean checkSql(String sql);
Map<String,List<ValueCalculateScopeDTO>> listAtomicIndexAttributeScope(List<String> atomicIndexIds);
GraphDebugResVO graphDebug(GraphDebugReqVO graphDebugDTO);
}

@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlSelectParser;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -20,20 +19,32 @@ import com.supervision.common.domain.R;
import com.supervision.common.utils.IPages;
import com.supervision.common.utils.StringUtils;
import com.supervision.constant.DataStatus;
import com.supervision.neo4j.dto.WebRelDTO;
import com.supervision.neo4j.service.Neo4jService;
import com.supervision.police.domain.*;
import com.supervision.police.dto.*;
import com.supervision.police.dto.indexRule.IndexRule;
import com.supervision.police.dto.indexRule.RuleCondition;
import com.supervision.police.dto.indexRule.RuleConditionGroup;
import com.supervision.police.dto.neo4j.NodeDTO;
import com.supervision.police.dto.neo4j.PathDTO;
import com.supervision.police.dto.neo4j.RelationshipValueDTO;
import com.supervision.police.mapper.CasePersonMapper;
import com.supervision.police.mapper.ModelAtomicResultMapper;
import com.supervision.police.mapper.ModelIndexMapper;
import com.supervision.police.service.*;
import com.supervision.police.vo.GraphDebugReqVO;
import com.supervision.police.vo.GraphDebugResVO;
import com.supervision.police.vo.ModelIndexReqVO;
import com.supervision.utils.JudgeLogicUtil;
import com.supervision.utils.SqlParserUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.Record;
import org.neo4j.driver.internal.InternalNode;
import org.neo4j.driver.internal.InternalRelationship;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -75,6 +86,8 @@ public class ModelIndexServiceImpl extends ServiceImpl<ModelIndexMapper, ModelIn
@Value("${case.evidence.table}")
private List<String> allowedTables;
private final Neo4jService neo4jService;
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> selectAll(ModelIndexReqVO modelIndex, Integer page, Integer size) {
@ -400,6 +413,161 @@ public class ModelIndexServiceImpl extends ServiceImpl<ModelIndexMapper, ModelIn
return result;
}
@Override
public GraphDebugResVO graphDebug(GraphDebugReqVO graphDebugDTO) {
GraphDebugResVO graphDebugResVO = new GraphDebugResVO();
if (StrUtil.isEmpty(graphDebugDTO.getCaseId())){
graphDebugResVO.setMessageType("2");
graphDebugResVO.setMessage("请选择案件!");
return graphDebugResVO;
}
CasePerson casePerson = casePersonMapper.selectOne(new LambdaQueryWrapper<>(CasePerson.class).eq(CasePerson::getCaseId, graphDebugDTO.getCaseId()).eq(CasePerson::getRoleCode, "1"));
Map<String, Object> parameters = new HashMap<>();
parameters.put("caseId", graphDebugDTO.getCaseId());
if (null != casePerson){
parameters.put("lawActor", casePerson.getId());
}
// 执行查询语句
List<Record> records;
try {
records = this.neo4jService.executeCypher(graphDebugDTO.getQueryLang(), parameters);
} catch (Exception e) {
graphDebugResVO.setMessageType("1");
graphDebugResVO.setMessage(e.getMessage());
return graphDebugResVO;
}
graphDebugResVO.setRecordList(mapRecords(records));
graphDebugResVO.setGraphRelList(generateRelations(records));
graphDebugResVO.setGraphNodeList(generateNodes(records));
// 尝试转换为图形数据
return graphDebugResVO;
}
private List<WebRelDTO> generateRelations(List<Record> records) {
List<WebRelDTO> graphRelList = records.stream().flatMap(record -> record.values().stream())
.filter(value -> value.type().name().equals("RELATIONSHIP"))
.map(value -> {
Relationship relationship = value.asRelationship();
return new WebRelDTO(relationship.id(), relationship.endNodeId(), relationship.type());
})
.collect(Collectors.toList());
// 拓展关系信息
Set<Long> relationIds = new HashSet<>();
for (Record record : records) {
// relId
org.neo4j.driver.Value relValue = record.get("relId");
if (StrUtil.equalsAny(relValue.type().name(), "INTEGER")){
relationIds.add(relValue.asLong());
}
}
if (CollUtil.isNotEmpty(relationIds)){
List<Record> extendRecord = neo4jService.executeCypher("MATCH ()-[r]-() where id(r) in $relationIds return r", Map.of("relationIds", relationIds));
if (CollUtil.isNotEmpty(extendRecord)){
graphRelList.addAll(extendRecord.stream().flatMap(r -> r.values().stream()).map(r -> {
Relationship relationship = r.asRelationship();
return new WebRelDTO(relationship.startNodeId(), relationship.endNodeId(), relationship.type());
}).toList());
}
}
return graphRelList;
}
private List<Map<String, Object>> generateNodes(List<Record> records) {
List<Map<String, Object>> graphNodeList = records.stream().flatMap(record -> record.values().stream())
.filter(value -> value.type().name().equals("NODE")).map(value ->{
Map<String, Object> map = new HashMap<>();
Node node = value.asNode();
map.put("id", node.id());
map.put("name", node.get("name").asString());
map.put("entityName", node.get("name").asString());
return map;
}
).collect(Collectors.toList());
// 拓展节点信息
Set<Long> nodeIds = new HashSet<>();
for (Record record : records) {
// startId ,endId
org.neo4j.driver.Value startValue = record.get("startId");
org.neo4j.driver.Value endValue = record.get("endId");
if (StrUtil.equalsAny(startValue.type().name(), "INTEGER")){
nodeIds.add(startValue.asLong());
}
if (StrUtil.equalsAny(endValue.type().name(), "INTEGER")){
nodeIds.add(endValue.asLong());
}
}
if (CollUtil.isNotEmpty(nodeIds)){
List<Record> extendRecord = neo4jService.executeCypher("MATCH (n) where id(n) in $nodeIds return n", Map.of("nodeIds", nodeIds));
if (CollUtil.isNotEmpty(extendRecord)){
graphNodeList.addAll(extendRecord.stream().flatMap(r -> r.values().stream()).map(r -> {
Map<String, Object> map = new HashMap<>();
map.put("id", r.asNode().id());
map.put("name", r.get("name").asString());
map.put("entityName", r.get("name").asString());
return map;
}).toList());
}
}
return graphNodeList;
}
private List<Map<String, Object>> mapRecords(List<Record> records) {
List<Map<String, Object>> recordList = new ArrayList<>();
for (Record record : records) {
HashMap<String, Object> map = new HashMap<>();
for (String key : record.keys()) {
org.neo4j.driver.Value value = record.get(key);
String typeName = value.type().name();
if (typeName.equals("NULL")){
map.put(key,null);
}
if (StrUtil.equalsAny(typeName, "BOOLEAN","STRING", "NUMBER", "INTEGER", "FLOAT")){
// MATCH (n)-[r]-() where n.caseId= '1' RETURN n.recordId limit 10
map.put(key,value.asObject());
}
if (typeName.equals("PATH")){
// MATCH p=(n)-[*2]-() where n.caseId= '1' RETURN p limit 10
map.put(key,new PathDTO(value.asPath()));
}
if (typeName.equals("RELATIONSHIP")){
// MATCH (n)-[r]-() where n.caseId= '1' RETURN r limit 10
map.put(key,new RelationshipValueDTO((InternalRelationship) value.asRelationship()));
}
if (typeName.equals("LIST OF ANY?")){
List<RelationshipValueDTO> list = value.asList().stream()
.map(i -> new RelationshipValueDTO((InternalRelationship) i)).toList();
map.put(key,list);
}
if (typeName.equals("NODE")){
// MATCH (n)-[r]-() where n.caseId= '1' RETURN r limit 10
map.put(key,new NodeDTO((InternalNode) value.asNode()));
}
recordList.add(map);
}
}
return recordList;
}
private List<ValueCalculateScopeDTO> makeScopes(String atomicIndexId, List<ModelAtomicIndex> atomicIndexList, List<NotePrompt> notePrompts, Map<String, String> dicMap) {
ModelAtomicIndex modelAtomicIndex = atomicIndexList.stream().filter(i -> StrUtil.equals(atomicIndexId, i.getId())).findFirst().orElse(null);
if (null == modelAtomicIndex || StrUtil.isEmpty(modelAtomicIndex.getPromptId())) {

@ -0,0 +1,34 @@
package com.supervision.police.vo;
import lombok.Data;
import java.util.List;
/**
*
*/
@Data
public class GraphDebugReqVO {
/**
* id
*/
private String caseId;
/**
* id
*/
private String atomicIndexId;
/**
*
*/
private String queryLang;
/**
* id
*/
private List<String> lawActorIdList;
}

@ -0,0 +1,34 @@
package com.supervision.police.vo;
import com.supervision.neo4j.dto.WebRelDTO;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class GraphDebugResVO {
/**
* 0: 1: 2
*/
private String messageType = "0";
private String message;
/**
*
*/
private List<Map<String,Object>> recordList;
/**
*
*/
private List<WebRelDTO> graphRelList;
/**
* name/entityName/id
*/
private List<Map<String, Object>> graphNodeList;
}
Loading…
Cancel
Save