Merge remote-tracking branch 'origin/dev_1.0.0' into dev_1.0.0

topo_dev
xueqingkun 10 months ago
commit 6ae8570861

@ -6,6 +6,7 @@ import com.supervision.neo4j.domain.Rel;
import com.supervision.neo4j.service.Neo4jService; import com.supervision.neo4j.service.Neo4jService;
//import io.swagger.annotations.Api; //import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation; //import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -23,13 +24,25 @@ public class Neo4jController {
private Neo4jService neo4jService; private Neo4jService neo4jService;
@PostMapping("/save") @PostMapping("/save")
public R<?> save(@RequestBody CaseNode caseNode) { public R<CaseNode> save(@RequestBody CaseNode caseNode) {
return neo4jService.save(caseNode); try {
CaseNode save = neo4jService.save(caseNode);
return R.ok(save);
} catch (RuntimeException e) {
return R.fail(e.getMessage());
}
} }
@PostMapping("/delNode") @PostMapping("/delNode")
public R<?> delNode(Long id) { public R<?> delNode(Long id) {
return neo4jService.delNode(id); neo4jService.delNode(id);
return R.ok();
}
@PostMapping("/deleteRel")
public R<?> deleteRel(Long relId) {
neo4jService.deleteRel(relId);
return R.ok();
} }
@PostMapping("/findById") @PostMapping("/findById")
@ -81,4 +94,16 @@ public class Neo4jController {
return neo4jService.test(); return neo4jService.test();
} }
@ApiOperation("构建抽象图谱")
@GetMapping("createAbstractGraph")
public void createAbstractGraph(String path, String sheetName) {
neo4jService.createAbstractGraph(path, sheetName);
}
@ApiOperation("清除抽象图谱")
@GetMapping("deleteAbstractGraph")
public void deleteAbstractGraph() {
neo4jService.deleteAbstractGraph();
}
} }

@ -55,4 +55,10 @@ public class CaseNode {
this.picType = picType; this.picType = picType;
} }
public CaseNode( String name, String nodeType, String picType){
this.name = name;
this.nodeType = nodeType;
this.picType = picType;
}
} }

@ -14,6 +14,8 @@ public class Rel {
private String target; private String target;
private Long targetId; private Long targetId;
// 是否是抽象,0抽象 1真实
private String picType = "1";
public Rel() { public Rel() {
} }
@ -24,6 +26,13 @@ public class Rel {
this.targetId = targetId; this.targetId = targetId;
} }
public Rel(Long sourceId, String name, Long targetId,String picType) {
this.sourceId = sourceId;
this.name = name;
this.targetId = targetId;
this.picType = picType;
}
public Rel(Long id, String source, Long sourceId, String name, String target, Long targetId) { public Rel(Long id, String source, Long sourceId, String name, String target, Long targetId) {
this.id = id; this.id = id;
this.source = source; this.source = source;

@ -12,9 +12,11 @@ import java.util.List;
*/ */
public interface Neo4jService { public interface Neo4jService {
R<?> save(CaseNode caseNode); CaseNode save(CaseNode caseNode);
R<?> delNode(Long id); void delNode(Long id);
void deleteRel(Long relId);
CaseNode findById(Long id); CaseNode findById(Long id);
@ -28,4 +30,8 @@ public interface Neo4jService {
R<?> getNode(String picType, String caseId); R<?> getNode(String picType, String caseId);
R<?> test(); R<?> test();
void deleteAbstractGraph();
void createAbstractGraph(String path,String sheetName);
} }

@ -1,42 +1,47 @@
package com.supervision.neo4j.service.impl; 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.domain.R;
import com.supervision.common.utils.StringUtils; import com.supervision.common.utils.StringUtils;
import com.supervision.neo4j.domain.CaseNode; import com.supervision.neo4j.domain.CaseNode;
import com.supervision.neo4j.domain.Rel; import com.supervision.neo4j.domain.Rel;
import com.supervision.neo4j.service.Neo4jService; import com.supervision.neo4j.service.Neo4jService;
import com.supervision.neo4j.utils.Neo4jUtils; 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.*;
import org.neo4j.driver.Record; import org.neo4j.driver.Record;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* @author qmy * @author qmy
* @since 2023-10-26 * @since 2023-10-26
*/ */
@Slf4j
@Service @Service
public class Neo4jServiceImpl implements Neo4jService { public class Neo4jServiceImpl implements Neo4jService {
private final Driver driver; private final Driver driver;
@Autowired @Autowired
private Neo4jServiceImpl(Driver driver) { private Neo4jServiceImpl(Driver driver) {
this.driver = driver; this.driver = driver;
} }
@Override @Override
public R<?> save(CaseNode caseNode) { public CaseNode save(CaseNode caseNode) {
if (StringUtils.isEmpty(caseNode.getName()) || StringUtils.isEmpty(caseNode.getNodeType())) { 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()); List<CaseNode> byName = findByName(caseNode.getCaseId(), caseNode.getRecordsId(), caseNode.getNodeType(), caseNode.getName(), caseNode.getPicType());
if (byName != null && !byName.isEmpty()) { if (byName != null && !byName.isEmpty()) {
return R.fail("名称已存在"); throw new RuntimeException("名称已存在!");
} }
CaseNode res = null; CaseNode res = null;
try { try {
@ -67,20 +72,50 @@ public class Neo4jServiceImpl implements Neo4jService {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return R.ok(res); return res;
} }
/**
* ,,,,
*
* @param id ID
*/
@Override @Override
public R<?> delNode(Long id) { public void delNode(Long id) {
try { try {
Session session = driver.session(); Session session = driver.session();
StringBuffer cql = new StringBuffer(); StringBuffer cql = new StringBuffer();
cql.append("MATCH (n) where id(n) = ").append(id).append(" DELETE n"); 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()); Result run = session.run(cql.toString());
while (run.hasNext()) {
Record next = run.next();
// log.info(next.toString());
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return R.ok();
} }
@Override @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); 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()) { while (run.hasNext()) {
Record record = run.next(); Record record = run.next();
String id = record.get("startId").asLong() + "";
String endId = record.get("endId").asLong() + ""; String id = Neo4jUtils.valueTransportString(record.get("startId"));
String relId = record.get("relId").asLong() + ""; String endId = Neo4jUtils.valueTransportString(record.get("endId"));
String relId = Neo4jUtils.valueTransportString(record.get("relId"));
System.out.println("************" + id); System.out.println("************" + id);
System.out.println("************" + endId); System.out.println("************" + endId);
System.out.println("************" + relId); System.out.println("************" + relId);
} }
return R.ok("222"); 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;
}
} }

@ -103,7 +103,7 @@ public class Neo4jUtils {
/** /**
* neo4j * neo4j
*/ */
private static String valueTransportString(Value value) { public static String valueTransportString(Value value) {
if (value instanceof NullValue) { if (value instanceof NullValue) {
return null; return null;
} else if (value instanceof IntegerValue) { } else if (value instanceof IntegerValue) {

@ -87,6 +87,11 @@ public class RecordController {
return R.ok(modelRecordTypeService.getThreeInfo(caseId, name, recordId)); return R.ok(modelRecordTypeService.getThreeInfo(caseId, name, recordId));
} }
@GetMapping("testExtractThreeInfo")
public void testExtractThreeInfo(){
modelRecordTypeService.testExtractThreeInfo();
}
@ApiOperation("将三元组信息保存到知识图谱") @ApiOperation("将三元组信息保存到知识图谱")
@PostMapping("/addNeo4j") @PostMapping("/addNeo4j")
public R<String> addNeo4j(@RequestBody ListDTO list) { public R<String> addNeo4j(@RequestBody ListDTO list) {

@ -22,5 +22,7 @@ public interface ModelRecordTypeService extends IService<ModelRecordType> {
List<TripleInfo> getThreeInfo(String caseId, String name, String recordId); List<TripleInfo> getThreeInfo(String caseId, String name, String recordId);
void testExtractThreeInfo();
String addNeo4j(List<String> ids); String addNeo4j(List<String> ids);
} }

@ -119,16 +119,60 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
} }
@Override @Override
public List<TripleInfo> getThreeInfo(String caseId, String name, String recordId) { public List<TripleInfo> getThreeInfo(String caseId, String name, String recordId) {
// TODO 这里应该改成异步的形式,通过异步的形式来进行提取三元组信息,不能每次点击就跑一遍 // TODO 这里应该改成异步的形式,通过异步的形式来进行提取三元组信息,不能每次点击就跑一遍
return extractTripleInfo(caseId, name, recordId); return extractTripleInfo(caseId, name, recordId);
} }
@Override
public void testExtractThreeInfo() {
String prompt = """
---
?
---
(:;:;:)
,json
,{"主体":"主体名称","关系":"关系名称","客体":"客体名称"}
::,.:{"主体":"小明","关系":"伪造","客体":"租车合同"}
:,:{}
!
JSON
""";
// 抽取的客体名称一定属于给定的客体类型分类,且抽取的关系完全等于给定的关系。
Prompt ask = new Prompt(new UserMessage(prompt));
StopWatch stopWatch = new StopWatch();
stopWatch.start();
log.info("开始分析:");
ChatResponse call = chatClient.call(ask);
stopWatch.stop();
log.info("耗时:{}", stopWatch.getTotalTimeSeconds());
String content = call.getResult().getOutput().getContent();
log.info("分析的结果是:{}", content);
String oldPrompt = """
1.
{result
[
{startNodeType:'LawActor',entity:'',endNodeType:'FictionalOrgan',property:'',value:'' },
{startNodeType:'LawActor',entity:'',endNodeType:'Seal',property:'',value:''},
{startNodeType:'LawActor',entity:'',endNodeType:'BusinessLicense',property:'',value:''}
]
}
2.
3.{ "result": [] }
1便QQ
{"result":[{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"FictionalOrgan","property":"兰州胜利机械租赁有限公司","value":"冒充"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"Seal","property":"兰州胜利机械租赁有限公司合同专用章","value":"伪造"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"Seal","property":"中铁北京局集团有限公司合同专用章","value":"伪造"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"BusinessLicense","property":"兰州胜利机械租赁有限公司营业执照","value":"伪造"}]}
2:{ "result": [] }
""";
}
private List<TripleInfo> extractTripleInfo(String caseId, String name, String recordId) { private List<TripleInfo> extractTripleInfo(String caseId, String name, String recordId) {
// 首先获取所有切分后的笔录 // 首先获取所有切分后的笔录
List<NoteRecordSplit> recordSplitList= noteRecordSplitMapper.selectRecord(caseId, name, recordId); List<NoteRecordSplit> recordSplitList = noteRecordSplitMapper.selectRecord(caseId, name, recordId);
List<TripleInfo> tripleInfos = new ArrayList<>(); List<TripleInfo> tripleInfos = new ArrayList<>();
// 对切分后的笔录进行遍历 // 对切分后的笔录进行遍历
for (NoteRecordSplit record : recordSplitList) { for (NoteRecordSplit record : recordSplitList) {
@ -189,7 +233,7 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
CaseNode startNode = neo4jService.findOneByName(tripleInfo.getCaseId(), tripleInfo.getNoteRecordsId(), tripleInfo.getStartNodeType(), start, "1"); CaseNode startNode = neo4jService.findOneByName(tripleInfo.getCaseId(), tripleInfo.getNoteRecordsId(), tripleInfo.getStartNodeType(), start, "1");
if (startNode == null) { if (startNode == null) {
startNode = new CaseNode(start, tripleInfo.getStartNodeType(), tripleInfo.getNoteRecordId(), tripleInfo.getNoteRecordsId(), tripleInfo.getCaseId(), "1"); startNode = new CaseNode(start, tripleInfo.getStartNodeType(), tripleInfo.getNoteRecordId(), tripleInfo.getNoteRecordsId(), tripleInfo.getCaseId(), "1");
CaseNode save = (CaseNode) neo4jService.save(startNode).getData(); CaseNode save = neo4jService.save(startNode);
startNode.setId(save.getId()); startNode.setId(save.getId());
} }
//结束节点 //结束节点
@ -197,7 +241,7 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
CaseNode endNode = neo4jService.findOneByName(tripleInfo.getCaseId(), tripleInfo.getNoteRecordsId(), tripleInfo.getEndNodeType(), end, "1"); CaseNode endNode = neo4jService.findOneByName(tripleInfo.getCaseId(), tripleInfo.getNoteRecordsId(), tripleInfo.getEndNodeType(), end, "1");
if (endNode == null) { if (endNode == null) {
endNode = new CaseNode(end, tripleInfo.getEndNodeType(), tripleInfo.getNoteRecordId(), tripleInfo.getNoteRecordsId(), tripleInfo.getCaseId(), "1"); endNode = new CaseNode(end, tripleInfo.getEndNodeType(), tripleInfo.getNoteRecordId(), tripleInfo.getNoteRecordsId(), tripleInfo.getCaseId(), "1");
CaseNode save = (CaseNode) neo4jService.save(endNode).getData(); CaseNode save = neo4jService.save(endNode);
endNode.setId(save.getId()); endNode.setId(save.getId());
} }
//关系 //关系

@ -20,6 +20,8 @@ spring:
top-k: 90 top-k: 90
# 与top-k一起工作。较高的值例如0.95将导致更加多样化的文本而较低的值例如0.5)将生成更加集中和保守的文本。 # 与top-k一起工作。较高的值例如0.95将导致更加多样化的文本而较低的值例如0.5)将生成更加集中和保守的文本。
top-p: 0.95 top-p: 0.95
# 随机数种子,用于控制模型输出的随机性。
seed: 1
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
druid: druid:

Loading…
Cancel
Save