package com.clinicalresearch.core.utils.Neo4jUtils;
import com.clinicalresearch.core.utils.Collections.CreateFileUtil;
import com.csvreader.CsvReader;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONObject;
import org.neo4j.driver.v1.*;
import org.neo4j.driver.v1.types.Node;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import static org.neo4j.driver.v1.Values.parameters;
/**
* Created by liangguannan on 2019/12/24.
*/
public class Neo4jSessionTest {
public final static ObjectMapper mapper = new ObjectMapper();
public static Session session=null;
public static Driver driver=null;
static {
/**
* 使用neo4j的session执行条件语句statement,一定要使用这个反序列化对象为json字符串
* 下面的设置的作用是,比如对象属性字段name="李二明",正常反序列化json为 == "name":"李二明"
* 如果使用下面的设置后,反序列name就是 == name:"appleyk"
* 而session执行语句create (:儿子{"name":"李二明","uuid":3330,"age":12,"height":"165cm"})会报错
* 因此,......etc
*/
mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
driver = GraphDatabase.driver( "bolt://10.10.202.118:7687", AuthTokens.basic( "neo4j", "123456" ) );
session = driver.session();
}
public static void createNodeAndRelation() throws Exception {
/**
* 建立一个爸爸与儿子的关系
*/
// 1.首先创建爸爸节点
RNode rDad = new RNode();
rDad.setUuid(1110);
rDad.setLabel("爸爸");
// 2.其次为爸爸节点添加属性 == Property Keys
rDad.addProperty("uuid", 1110);
rDad.addProperty("name", "李大明");
rDad.addProperty("age", 45);
rDad.addProperty("height", "182.5cm");
// 3.添加关系
REdge edge = new REdge();
edge.addProperty("relationID", 521);
edge.addProperty("time", "1997-05-12");
edge.setRelationID(521);
edge.setName("父亲");
// 4.为关系节点添加指向节点 == 创建儿子节点
RNode rSon = new RNode();
rSon.setUuid(2220);
rSon.setLabel("儿子");
// 5.为儿子节点添加属性 == Property Keys
rSon.addProperty("uuid", 2220);
rSon.addProperty("name", "李小明");
rSon.addProperty("age", 20);
rSon.addProperty("height", "185cm");
// 6.给爸爸节点添加关系
rDad.setEdge(edge);
createNode(rDad);
createNode(rSon);
createRelation(rDad,rSon);
System.err.println("创建成功");
}
/**
* 创建节点
* @param rNode
* @throws Exception
*/
public static void createNode(RNode rNode) throws Exception{
RNode srcNode = queryNode(rNode);
//查node是否已經存在了,不存在則創建
if(srcNode == null){
String propertiesString = mapper.writeValueAsString(rNode.getProperties());
String cypherSql = String.format("create (:%s%s)", rNode.getLabel(), propertiesString);
System.out.println(cypherSql);
session.run(cypherSql);
System.err.println("创建节点:"+rNode.getLabel()+"成功!");
}else{
System.err.println("节点已存在,跳过创建");
}
}
/**
* 创建关系
* @param srcNode
* @param tarNode
* @throws Exception
*/
public static void createRelation(RNode srcNode,RNode tarNode) throws Exception{
REdge edge = queryRelation(srcNode,tarNode);
if(edge == null){
edge = srcNode.getEdge();
String propertiesString = mapper.writeValueAsString(edge.getProperties());
String cypherSql = String.format("match(a),(b) where a.uuid=%d and b.uuid=%d create (a)-[r:%s %s]->(b)",
srcNode.getUuid(),tarNode.getUuid(),
edge.getName(), propertiesString);
System.out.println(cypherSql);
session.run(cypherSql);
System.err.println("创建关系:"+edge.getName()+"成功!");
}else{
System.err.println("关系已存在,跳过创建");
}
}
/**
* 查询节点
*
* @param rNode
* @return
*/
public static RNode queryNode(RNode rNode) {
RNode node = null;
REdge redge=rNode.getEdge();
String cypherSql = String.format("match(n:%s) where n.%s = %d return n",redge.getLabel(), redge.getNodeIdName(), rNode.getUuid());
StatementResult result = session.run(cypherSql);
if (result.hasNext()) {
Record record = result.next();
for (Value value : record.values()) {
/**
* 结果里面只要类型为节点的值
*/
if (value.type().name().equals("NODE")) {
Node noe4jNode = value.asNode();
node = new RNode();
node.setLabel(rNode.getLabel());
node.setProperties(noe4jNode.asMap());
}
}
}
return node;
}
/**
* 查询关系
* @param srcNode
* @param tarNode
* @return
*/
public static REdge queryRelation(RNode srcNode,RNode tarNode){
REdge edge = srcNode.getEdge();
String cypherSql =String.format("match(n)-[r:%s]-(b) where n.%s = %d and b.%s = %d return r",
edge.getName(),srcNode.getNodeIdName(),srcNode.getUuid(),srcNode.getNodeIdName(),tarNode.getUuid());
StatementResult result = session.run(cypherSql);
if(result.hasNext()){
return edge;
}
return null;
}
/**
* 读取CSV文件
* @param diseaseName
* @param filePath :全路径名
* @param type
* @param nodeIdName
*/
public static List<String[]> readCSV(String diseaseName, String filePath, String type, String nodeIdName) throws Exception {
CsvReader reader = null;
List<String[]> dataList = new ArrayList<String[]>();
char separator = ',';
try {
//如果生产文件乱码,windows下用gbk,linux用UTF-8
reader = new CsvReader(filePath, separator, Charset.forName("UTF-8"));
// 读取表头
reader.readHeaders();
String[] headArray = reader.getHeaders();//获取标题
System.out.println(headArray[0] +" " + headArray[1] + " " + headArray[2]);
// 逐条读取记录,直至读完
while (reader.readRecord()) {
// 读一整行
System.out.println("读一整行 "+reader.getRawRecord());
// 读这行的第一列
System.out.println("读这行的第一列: "+reader.get(0));//id
// 读这行的第二列
System.out.println("读这行的第二列: "+reader.get(1));//title
System.out.println("读这行的第三列: "+reader.get(2));//level
if ("Node".equals(type)){
createNodeTest(diseaseName,Integer.valueOf(reader.get(0)),reader.get(1),reader.get(2),reader.get(3),nodeIdName);
}else {
createRelationTest(reader.get(2),Integer.valueOf(reader.get(0)),Integer.valueOf(reader.get(1)),nodeIdName);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != reader) {
reader.close();
}
}
return dataList;
}
/**
* 数据 创建节点
* @param diseaseName
* @param srcNodeUuid
* @param title
* @param level
* @param describe
* @param nodeIdName
* @throws Exception
*/
public static void createNodeTest(String diseaseName, int srcNodeUuid, String title, String level, String describe, String nodeIdName) throws Exception{
REdge edge1 = new REdge();
edge1.setLabel(diseaseName);
edge1.setTitle(title);
edge1.setNodeIdName(nodeIdName);
RNode rNode= new RNode();
rNode.setUuid(srcNodeUuid);
rNode.setEdge(edge1);
RNode srcNode = queryNode(rNode);
//查node是否已經存在了,不存在則創建
if(srcNode == null){
String cypherSql =String.format("CREATE (n:%s {%s: {%s}, title: {title}, level: {level}, describe: {describe}})",
diseaseName,nodeIdName,nodeIdName);//一个总的根节点
session.run(cypherSql,
parameters( nodeIdName, srcNodeUuid, "title", title,"level", level,"describe",describe) );
System.err.println("创建节点:"+edge1.getLabel()+"成功!");
}else{
System.err.println("节点已存在,跳过创建");
}
}
/**
* excel 数据 创建节点关系
* @param srcNodeUuid
* @param tarNodeUuid
* @param nodeIdName
* @throws Exception
*/
public static void createRelationTest(String name, int srcNodeUuid, int tarNodeUuid, String nodeIdName) throws Exception{
REdge edge1 = new REdge();
edge1.setName(name);
RNode srcNode= new RNode();
srcNode.setUuid(srcNodeUuid);
srcNode.setEdge(edge1);
srcNode.setNodeIdName(nodeIdName);
RNode tarNode= new RNode();
tarNode.setUuid(tarNodeUuid);
REdge edge = queryRelation(srcNode,tarNode);
if(edge == null){
edge = srcNode.getEdge();
String propertiesString = mapper.writeValueAsString(edge.getProperties());
String cypherSql = String.format("match(a),(b) where a.%s=%d and b.%s=%d create (a)-[r:%s %s]->(b)",
nodeIdName,srcNode.getUuid(),nodeIdName,tarNode.getUuid(),
edge.getName(), propertiesString);
System.out.println(cypherSql);
session.run(cypherSql);
System.err.println("创建关系:"+edge.getName()+"成功!");
}else{
System.err.println("关系已存在,跳过创建");
}
}
/**
* 知识图谱 节点数据
* @throws Exception
* @param diseaseName
*/
public static void createNodeByFile(String diseaseName) throws Exception{
String type="Node";
List<JSONObject> list=CreateFileUtil.readfile("C:\\Users\\liangguannan\\Desktop\\neo4j数据\\脑梗塞\\node");
for (int i=0;i<list.size();i++){
JSONObject jsonObject=list.get(i);
String filePath=jsonObject.get("path").toString();
String nodeIdName=diseaseName+"_nodeId";
readCSV(diseaseName,filePath,type,nodeIdName);
}
}
/**
* 知识图谱 关系数据
* @throws Exception
* @param diseaseName
*/
public static void createRelationByFile(String diseaseName) throws Exception{
String type="Relation";
List<JSONObject> list=CreateFileUtil.readfile("C:\\Users\\liangguannan\\Desktop\\neo4j数据\\脑梗塞\\relation");
for (int i=0;i<list.size();i++){
JSONObject jsonObject=list.get(i);
String filePath=jsonObject.get("path").toString();
String nodeId=diseaseName+"_nodeId";
String name=null;
readCSV(name,filePath,type,nodeId);
}
}
public static void main(String[] args) {
try {
//createNodeAndRelation();
String name="cerebralInfarction";
createNodeByFile(name);//读取文件夹下的节点excel集合
createRelationByFile(name);//读取文件夹下关系excel集合
//createRelationTest(50001,7);
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
driver.close();
}
}
}
package com.clinicalresearch.core.utils.Neo4jUtils;
/**
* Created by on 2019/12/24.
*/
public class RNode extends RObject {
/**
* 节点的uuid == 对应其他数据库中的主键
*/
private int uuid;
/**
* 节点里面是否包含有边 == 关系
*/
private REdge edge;
public Integer getUuid() {
return uuid;
}
public void setUuid(Integer uuid) {
this.uuid = uuid;
}
public REdge getEdge() {
return edge;
}
public void setEdge(REdge edge) {
this.edge = edge;
}
}
package com.clinicalresearch.core.utils.Neo4jUtils;
/**
* 边 == 关系
* Created by liangguannan on 2019/12/24.
*/
public class REdge extends RObject {
/**
* 关系的ID == 聚合、连接、属于、包括等,这些关系可能是枚举字典,因此记录关系ID是有必要的
*/
private int relationID;
/**
* 关系名称
*/
private String name;
/**
* 关系指向哪一个节点 == 可能这个节点还有关系【节点关系递增下去】
*/
private RNode rNode;
public Integer getRelationID() {
return relationID;
}
public void setRelationID(Integer relationID) {
this.relationID = relationID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public RNode getrNode() {
return rNode;
}
public void setrNode(RNode rNode) {
this.rNode = rNode;
}
}
package com.clinicalresearch.core.utils.Neo4jUtils;
import java.util.HashMap;
import java.util.Map;
/**
* 节点和关系对象的基类,含公共部分的id、标签label以及属性properties
* Created by liangguannan on 2019/12/24.
*/
public class RObject {
/**
* 节点标签名称 == Node Labels
*/
private String label;
/**
* 节点标题
*/
private String title;
/**
* 节点id的名称
*/
private String nodeIdName;
/**
* 节点属性键值对 == Property Keys
*/
private Map<String, Object> properties;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getNodeIdName() {
return nodeIdName;
}
public void setNodeIdName(String nodeIdName) {
this.nodeIdName = nodeIdName;
}
public RObject(){
properties = new HashMap<>();
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public Map<String, Object> getProperties() {
return properties;
}
/**
* 添加属性
* @param key
* @param value
*/
public void addProperty(String key,Object value){
properties.put(key, value);
}
/**
* 拿到属性
* @param key
* @return
*/
public Object getProperty(String key){
return properties.get(key);
}
/**
* 移除属性
* @param key
*/
public void removeProperty(String key){
properties.remove(key);
}
public void setProperties(Map<String, Object> properties) {
this.properties = properties;
}
}
读取Excel文件夹下的所有文件
package com.clinicalresearch.core.utils.Collections;
/**
* Created by liangguannan on 2018/5/4.
*/
import com.clinicalresearch.core.utils.JsonFormatTool;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.clinicalresearch.utils.HttpClientUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CreateFileUtil {
/**
* 生成.json格式文件
*/
public static boolean createJsonFile(String jsonString, String filePath, String fileName) {
// 标记文件生成是否成功
boolean flag = true;
// 拼接文件完整路径
String fullPath = filePath + File.separator + fileName + ".json";
// 生成json格式文件
try {
// 保证创建一个新文件
File file = new File(fullPath);
if (!file.getParentFile().exists()) {
// 如果父目录不存在,创建父目录
file.getParentFile().mkdirs();
}
if (file.exists()) {
// 如果已存在,删除旧文件
file.delete();
}
file.createNewFile();
// 格式化json字符串
jsonString = JsonFormatTool.formatJson(jsonString);
// 将格式化后的字符串写入文件
Writer write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
write.write(jsonString);
write.flush();
write.close();
} catch (Exception e) {
flag = false;
e.printStackTrace();
}
// 返回是否成功的标记
return flag;
}
/**
* 通过本地文件访问json并读取
* @param path:E:/svn/05.Hospital/templatedept_uuid.json
* @return:json文件的内容
*/
public static String ReadFile(String path){
String laststr="";
File file=new File(path);// 打开文件
BufferedReader reader=null;
try{
FileInputStream in = new FileInputStream(file);
reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));// 读取文件
String tempString=null;
while((tempString=reader.readLine())!=null){
laststr=laststr+tempString;
}
reader.close();
}catch(IOException e){
e.printStackTrace();
}finally{
if(reader!=null){
try{
reader.close();
}catch(IOException el){
}
}
}
return laststr;
}
/**
* 读取某个文件夹下的所有文件
*/
public static List<JSONObject> readfile(String filepath) throws FileNotFoundException, IOException {
List<JSONObject> list= new ArrayList();
try {
File file = new File(filepath);
if (!file.isDirectory()) {
System.out.println("文件");
System.out.println("path=" + file.getPath());
System.out.println("absolutepath=" + file.getAbsolutePath());
System.out.println("name=" + file.getName());
} else if (file.isDirectory()) {
System.out.println("文件夹");
String[] filelist = file.list();
for (int i = 0; i < filelist.length; i++) {
File readfile = new File(filepath + "\\" + filelist[i]);
if (!readfile.isDirectory()) {
System.out.println("path=" + readfile.getPath()+"========="+readfile.getName());
JSONObject jsonObject = new JSONObject();
jsonObject.put("path",readfile.getPath());
jsonObject.put("name",readfile.getName());
//getAllItems(readfile.getPath(),readfile.getName());
list.add(jsonObject);
} else if (readfile.isDirectory()) {
readfile(filepath + "\\" + filelist[i]);
}
}
}
} catch (FileNotFoundException e) {
System.out.println("readfile() Exception:" + e.getMessage());
}
return list;
}
public static void main(String[] args) {
}
}
测试数据网盘地址:
https://share.weiyun.com/TfBlKS4t