- 简要
- 思路
- 源代码
前言:在这篇博客里,直接获取了节点的单层关系,针对需要获取节点的多层关系的情形,笔者在这篇博客中解决该问题。
个人依赖配置:依赖包参考获取Neo4j节点的所有信息这篇博客。
利用Neo4j的Java驱动获取节点的多层关系并发往前端的思路很简单,主要分为三步:
Step1:前端发送信息,构建出Cypher语句
Step2:利用Neo4j的Java驱动使用该Cypher语句查询Neo4j,获得查询结果
Step3:对查询结果进行处理并封装成JSON格式数据发送到前端
显然,步骤 1和步骤2都比较简单,所以笔者重点描述步骤3,讨论怎样处理查询结果并且如何进行封装处理才能使前端人员处理数据比较方便。不过在描述步骤3之前,回顾下查询节点的多层关系的cypher语句。`
match data=(n:Person{name:'xiaoWang'})-[*1..3]->(m) return data
上述就是一个查询name为xiaoWang的人的所有深度为三层以内的关系的Cypher语句。查询结果如下图所示:
实际查询得到的值里包含了大量重复的值,由于数据量比较大,不好展示,读者可以自己试试。
显然,我们指向获取这8条关系,那么怎办呢?
对于重复数据,我们想到了HashXX系列的容器;
由于关系是较为乱的,如何保证三元组之间准确呢?
答案是,将三元组的主谓宾拼接成一个字符串存储在HashXX容器中。例如该字符串形式为:(首节点类型)首节点名_关系_(尾节点类型)尾节点名
Person_Xiaowang/HasBought/Computer_lennove
这样做的好处在于一条语句描述了三元组,保证了三元组的准确性。前端接受到该数据后,仅需要几次字符串拆分即可(先用"/“拆分获取到起始节点,关系,和尾节点三个部分,再用”_"拆分起始节点和尾节点)
源代码源代码如下(获取三元组并存储与HashMap集合中):
package com.just.camkg.util;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Value;
import org.neo4j.driver.v1.types.Node;
import org.neo4j.driver.v1.types.Path;
import org.neo4j.driver.v1.types.Path.Segment;
import org.neo4j.driver.v1.types.Relationship;
import com.alibaba.fastjson.JSONObject;
import org.neo4j.driver.v1.Record;
public class GetCypherMuiltInfor {
private static Driver driver;
public static Map<String, Object> tripleMap = new LinkedHashMap();
//静态代码块,获取驱动
static {
//default port is 7687
String uri="bolt://localhost:7687";
String username = "neo4j";
String password = "liu197917";
driver = GraphDatabase.driver(uri,AuthTokens.basic(username,password));
}
public void close() {
driver.close();
}
// 查询功能
public void getMuiltGraphInfo(String cypher){
try(Session session = driver.session()){
StatementResult result = session.run(cypher); //获取查询结果值
LinkedHashSet<String>tripleSet = new LinkedHashSet();
while(result.hasNext()) {
Record record = result.next();
//System.out.println(record);
List<Value> value = record.values(); //查询记录值,每个记录中包含一个路径
for(Value i:value){
Path path = i.asPath();
/* 一个路径中存在多个三元组*/
Iterator<Segment> ss = path.iterator();
while(ss.hasNext()) {
Segment seg = ss.next();
Node stNode = seg.start();//三元组的首节点
Node edNode = seg.end();//三元组的尾节点
String stinf = stNode.get("name").asString() + "_" +
stNode.labels().iterator().next().toString(); // 笔者Neo4j中一个节点只有一个标签类型
//System.out.println(stNodeType);
String resinf = seg.relationship().type();
String eninf = edNode.get("name").asString() + "_" +
edNode.labels().iterator().next().toString();
String triple = stinf + "/" + resinf + "/" + eninf; //拼接成为三元组字符串
tripleSet.add(triple);
}
}
}
// 将获取到的结果存储的Map集合中,转为JSON的前提
Integer tempIndex = 0;
for(String triple : tripleSet) {
this.tripleMap.put(triple, (Object)tempIndex);
tempIndex++;
}
}
// this.close(); //关闭驱动 我们希望用户手动关闭,否则只用一次就报错
}
}
总结:1、个人使用感觉比较方便,不过前提是,对节点是有要求的,比如stNode.get(“name”)就是获取该节点的名 称,这要求查询的Neo4j中节点也是有name属性的。
2、用户前端获取后处理也方便,如果大家需要前端知识图谱化的,可以留言。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)