1、查询关系,返回开始节点,关系节点,结束节点
案例1:调用session.run(String var1, Map<String, Object> var2);方法
public static final String returnPara = "RETURN distinct {COMPANY_ID:sourceNodeInfo.COMPANY_ID,COMPANY_TYPE:sourceNodeInfo.COMPANY_TYPE_LIST,\n" +
" COMPANY_NM:sourceNodeInfo.COMPANY_NM,\n" +
" LABELS:Labels(sourceNodeInfo)} AS sourceNodeInfo,\n" +
"{id:ID(relationInfo),type:TYPE(relationInfo),\n" +
" investShaRatio:CASE WHEN relationInfo.SHA_RATIO IS NOT NULL THEN tofloat(relationInfo.SHA_RATIO)\n" +
" ELSE 0 END,\n" +
" GUAR_INFO:relationInfo.GUAR_INFO,controllerType:relationInfo.RELATION_TYPE,relativeType:relationInfo.RELATION_TYPE} AS relationInfo,\n" +
"{COMPANY_ID:targetNodeInfo.COMPANY_ID,COMPANY_TYPE:targetNodeInfo.COMPANY_TYPE_LIST,\n" +
" COMPANY_NM:targetNodeInfo.COMPANY_NM,\n" +
" LABELS:Labels(targetNodeInfo)} AS targetNodeInfo;";
public static final String returnQuery = "UNWIND relationships(P) AS R\n" +
"WITH startNode(R) AS sourceNodeInfo , R AS relationInfo, endNode(R) AS targetNodeInfo\n" +
Constants.returnPara;
String cypher = "MATCH p1 = (A1:COMPANY{COMPANY_ID:$COMPANY_ID })-[r1:INVEST*..1]-(d1) \n" +
"with p1 AS P UNWIND relationships(P) AS R\n" + returnQuery;
//param类型是Map<String,Object>
List<Record> result = new CypherUtil().executeWithParamsUpgrade(cypher,param);
for (Record record : result) {
Map<String, Object> copiedMap = Map2Map.copyMap(record.asMap());
ResultReturn resultReturn = new ResultReturn(
QueryResultMapper.MapNodeShowMapper((Map<String, Object>) copiedMap.get("sourceNodeInfo")),
QueryResultMapper.MapRelationShipShowMapper((Map<String, Object>) copiedMap.get("relationInfo")),
QueryResultMapper.MapNodeShowMapper((Map<String, Object>) copiedMap.get("targetNodeInfo")));
resultReturnCollection.add(resultReturn);
}
其中executeWithParamsUpgrade 方法如下,executorService是我定义的一个线程池
import org.neo4j.driver.Record;
import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
import org.neo4j.driver.exceptions.ServiceUnavailableException;
public class CypherUtil {
//自定义线程池
private static ExecutorService executorService = new ThreadPoolExecutor(8, 20, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(), new UserThreadFactory("cypher query"));
public List<Record> executeWithParamsUpgrade(String cypher, Map<String, Object> params) throws Exception {
FutureTask<List<Record>> futureTask = new FutureTask<>(new Callable<List<Record>>() {
@Override
public List<Record> call() {
log.debug("cypher: {}\n parameters: {}", cypher, params);
try (Session session = Constants.driver.session()) {
//主要是执行 session的run方法
return session.run(cypher, params).list();
}
}
});
try {
executorService.execute(futureTask);
return futureTask.get(5, TimeUnit.MINUTES);
} catch (InterruptedException | ExecutionException | ServiceUnavailableException | TimeoutException e) {
futureTask.cancel(true);
throw e;
}
}
}
对于cypher语句,解释如下: 其中 relationships()、startNode() 和 endNode() 是 Neo4j 的内置函数,用于处理图中的路径、关系和节点,其中param参数对象里面存储的是"COMPANY_ID":“xxxx”
执行流程:
1.MATCH:匹配所有从指定公司(COMPANY_ID)出发,通过 INVEST 关系(一跳)连接的节点,生成路径 p1。
2.WITH:将路径 p1 重命名为 P 传递到下一步。
3.UNWIND:将路径 P 中的所有关系展开为单独的行(此处最多 1 个关系)。
4.WITH:提取每个关系的起始节点、关系本身和终止节点,分别命名为 sourceNodeInfo、relationInfo 和 targetNodeInfo
对于 cppher语句的执行,主要是执行run方法,Session本身的方法如下
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.neo4j.driver;
import java.util.Map;
import org.neo4j.driver.util.Resource;
public interface Session extends Resource, QueryRunner {
Transaction beginTransaction();
Transaction beginTransaction(TransactionConfig var1);
<T> T readTransaction(TransactionWork<T> var1);
<T> T readTransaction(TransactionWork<T> var1, TransactionConfig var2);
<T> T writeTransaction(TransactionWork<T> var1);
<T> T writeTransaction(TransactionWork<T> var1, TransactionConfig var2);
Result run(String var1, TransactionConfig var2);
Result run(String var1, Map<String, Object> var2, TransactionConfig var3);
Result run(Query var1, TransactionConfig var2);
Bookmark lastBookmark();
/** @deprecated */
@Deprecated
void reset();
void close();
}
其父类接口QueryRunner的具体方法如下
package org.neo4j.driver;
import java.util.Map;
public interface QueryRunner {
Result run(String var1, Value var2);
Result run(String var1, Map<String, Object> var2);
Result run(String var1, Record var2);
Result run(String var1);
Result run(Query var1);
}
Result的具体方法如下
package org.neo4j.driver;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
import org.neo4j.driver.exceptions.NoSuchRecordException;
import org.neo4j.driver.summary.ResultSummary;
public interface Result extends Iterator<Record> {
List<String> keys();
boolean hasNext();
Record next();
Record single() throws NoSuchRecordException;
Record peek();
Stream<Record> stream();
List<Record> list();
<T> List<T> list(Function<Record, T> var1);
ResultSummary consume();
}