我通过GraphDatabaseService访问neo4j数据库。我添加了一些节点和关系,并希望进行查询。我的目标是让所有与endnode具有Calling关系的节点。所以我有这个节点的全部路径。 (例如:node1 -calling-> node2 -calling * - > nodeX -calling-> endnode)
我试过这样的事情:
GraphDatabaseService _graphDatabase; // db is running and working fine
Node node;//given by the function call
HashMap<String, Object> properties = Maps.newHashMap();
properties.put("name", getPropertyFromNode(node, "name"));
String query = "MATCH p=(startnode)-[rel:CALLING*]->(endnode) WHERE endnode.name = {name} RETURN p";
Result result = _graphDatabase.execute(query, properties);
while (result.hasNext()) {
Map<String, Object> next = result.next();
next.forEach((k, v) -> {
System.out.println(k + " : " + v.toString());
if (v instanceof PathImpl) {
PathImpl pathImpl = (PathImpl) v;
String startNodeName = getPropertyFromNode(pathImpl.startNode(), "name");
String endNodeName = getPropertyFromNode(pathImpl.endNode(), "name");
System.out.println(startNodeName + " -calling-> " + endNodeName);
}
});
}
public String getPropertyFromNode(Node node, String propertyName) {
String result = null;
try (Transaction transaction = _graphDatabase.beginTx()) {
result =node.getProperty(propertyName).toString();
transaction.success();
}
return result;
}
问题在于,结果是Map&lt;'String,Object&gt;,我想要获取关系中节点的id或名称。我试图将Object转换为PathImpl,因为这是返回的类型(通过调试计算出来),但它接口就像这个类在不同的类加载器中,因此语句instanceof返回false。 v.toString()返回id为的喜欢节点的String表示形式(例如:p:(24929) - [CALLING,108061] - &gt;(24930))
我的问题是,我能以更好的方式访问这些信息,或者我如何更改classLoader(如果这是问题,我正在gradle项目中使用eclipse)来进行转换。 我不想解析String以获取id并通过该属性从db获取节点,它的接缝对我来说很难看。
答案 0 :(得分:1)
如果要获取起始节点和结束节点的名称,则应修改Cypher代码以返回它们(而不是路径),这将大大简化从响应中提取数据所需的代码。例如:
MATCH p=(startnode)-[rel:CALLING*]->(endnode)
WHERE endnode.name = {name}
RETURN startnode.name AS s_name, endnode.name AS e_name, p;
答案 1 :(得分:0)
在尝试使用cybersam的有效答案来更改密码查询后,我发现了另一种不改变查询的方式,更适合我的目标。 对我来说,目标是获得整个路径不仅是链接节点的名称/ ID。该信息正是我想要的参数'p'(参见查询),但我无法转换该类型。 原因是Neo4j正在使用PathImpl的内部实现。 为了使我的解决方案在问题工作中,我必须使用Path而不是PathImpl,所以我不必导入实习生类型。所以我改变了进口:
import org.neo4j.graphalgo.impl.util.PathImpl;
到
import org.neo4j.graphdb.Path;
并测试Path而不是PathImpl。
if (v instanceof Path) {
Path path = (Path) v;
Iterable<Node> nodes = path.nodes();
nodes.forEach(n -> System.out.println(n.toString()));
}
现在我可以访问整个路径了。希望这也能帮助其他人。