package com.demo.service.graph;
import com.demo.api.graph.Edge;
import com.demo.api.graph.GraphService;
import com.demo.api.graph.Triplet;
import com.demo.api.graph.Vertex;
import org.neo4j.driver.v1.*;
import org.neo4j.driver.v1.summary.ResultSummary;
import javax.annotation.PreDestroy;
import java.util.List;
import static org.neo4j.driver.v1.Values.parameters;
public class implements GraphService{
Driver driver = GraphDatabase.driver(
"bolt://server:7687", AuthTokens.basic("neo4j", "password"));
* 添加节点
* 如果已经存在,不添加新节点,计数器加一
*
* @param vertexType
* @param vertexNameList
*/
public void addVertex(String vertexType, final List vertexNameList) {
try (Session session = driver.session()) {
session.writeTransaction(tx -> {
for (String vertexName : vertexNameList) {
String cypher = "MERGE (v:$vertexType {name: '$vertexName'}) " +
"on create SET v.count = 1 " +
"on match SET v.count = v.count + 1 " +
"return v";
cypher = cypher.replace("$vertexType", vertexType).replace("$vertexName", vertexName);
ResultSummary resultSummary = tx.run(cypher,
parameters("vertexName", vertexName)).consume();
}
return "success";
});
}
}
* 添加关系
*
* @param edgeName
* @param vertexType
* @param vertexNameList
*/
public void addEdges(String edgeName, String vertexType, List vertexNameList) {
try (Session session = driver.session()) {
session.writeTransaction(tx -> {
for (String vertexNameSource : vertexNameList) {
for (String vertexNameDest : vertexNameList) {
if (vertexNameSource.equals(vertexNameDest)) {
continue;
}
String cypher = "MATCH (source:$vertexType {name: '$vertexNameSource'})" +
"MATCH (dest:$vertexType {name: '$vertexNameDest'}) " +
" MERGE (source)-[edge:$edgeName]->(dest) " +
"on create SET edge.count = 1 " +
"on match SET edge.count = edge.count + 1 " +
"return edge.count";
cypher = cypher.replace("$vertexType", vertexType)
.replace("$edgeName", edgeName)
.replace("$vertexNameSource", vertexNameSource)
.replace("$vertexNameDest", vertexNameDest);
ResultSummary resultSummary = tx.run(cypher,
parameters("vertexNameSource", vertexNameSource,
"vertexNameDest", vertexNameDest)).consume();
}
}
return "success";
});
}
}
* Suggest
*
* @param vertexType
* @param prefix
* @param pageSize
* @param pageNo
* @return
*/
public List suggestVertexNames(String vertexType, String prefix, int pageSize, int pageNo) {
try (Session session = driver.session()) {
String cypher = "MATCH (a:$vertexType) " +
" WHERE a.name =~ '(?i)$prefix.*' " +
" WITH a, SIZE((a)-[]->()) as r_size " +
" ORDER BY SIZE(a.name) asc, r_size desc " +
" RETURN a, r_size " +
" SKIP $skipSize LIMIT $maxSize";
int skipSize = pageNo * pageSize;
cypher = cypher.replace("$vertexType", vertexType)
.replace("$prefix", prefix.replace(".", "\.").replace("*", "\*"))
.replace("$maxSize", String.valueOf(pageSize))
.replace("$skipSize", String.valueOf(skipSize));
List nodeNames = session.run(cypher).list(record -> {
String name = record.get("a").get("name", "prefix");
return name;
}
);
return nodeNames;
}
}
* 查询关联节点
*
* @param vertexType
* @param vertexName
* @param maxSize
* @return
*/
public List queryRelatives(String vertexType, String vertexName, int maxSize) {
try (Session session = driver.session()) {
String cypher = "MATCH (a:$vertexType {name: '$vertexName'})-[r]->(b:$vertexType) " +
" RETURN a,r,b " +
" ORDER BY r.count desc,b.count desc " +
" LIMIT $maxSize ";
cypher = cypher.replace("$vertexType", vertexType)
.replace("$vertexName", vertexName)
.replace("$maxSize", String.valueOf(maxSize));
List triplets = session.run(cypher).list((record) -> {
Value a = record.get("a");
Vertex source = new Vertex(a.get("name", ""), a.get("count", 1L));
Value b = record.get("b");
Vertex dest = new Vertex(b.get("name", ""), b.get("count", 1L));
Value r = record.get("r");
Edge edge = new Edge(r.asRelationship().type(), r.get("count", 1L));
Triplet triplet = new Triplet(source, edge, dest);
return triplet;
});
return triplets;
}
}
@PreDestroy
public void preDestroy() {
driver.close();
}
}