【问题标题】:Neo4j traversal APINeo4j 遍历 API
【发布时间】:2014-05-09 14:31:02
【问题描述】:

我是 Neo4j 的新手,但我花了一些时间阅读文档。我想我了解基本概念,而且我现在对 Cypher 查询非常有信心。不过,我在理解 Traversal API 的工作原理时遇到了问题(好吧,我没有得到预期的结果,所以我想我做错了什么)。

这是我的(非常)简单的模型(使用 API 创建):

  Node sugar = graphDb.createNode(LabelType.RAW_MATERIAL.getLabel());
  sugar.setProperty(PropertyType.NAME.getName(), "Sugar");
  Node caramel = graphDb.createNode(LabelType.RAW_MATERIAL.getLabel(), LabelType.COOKED_MEAL.getLabel());
  caramel.setProperty(PropertyType.NAME.getName(), "Caramel");

  caramel.createRelationshipTo(sugar, FoodRelationshipType.CONTAINS);

我想要实现的是获得“Caramel”:CONTAINS 的所有节点。我可以通过密码查询来做到这一点:

MATCH (:CookedMeal {name: 'Caramel'}) - [:CONTAINS] -> (rawMaterials)  return rawMaterials

在 Java 中,我执行了以下操作,但没有成功(因为它只返回我传递给“traverse()”方法的节点):

  TraversalDescription traversalDescription = graphDb.traversalDescription()
        .depthFirst()
        .relationships(FoodRelationshipType.CONTAINS, Direction.INCOMING);

  Traverser traverser = traversalDescription.traverse(
        Iterables.toArray(GlobalGraphOperations.at(graphDb).getAllNodesWithLabel(LabelType.COOKED_MEAL.getLabel()), Node.class)
  );

  for (Path path : traverser) {
      System.out.println(path.endNode());
  }

就像查询没有使用遍历relationships() 方法一样。知道为什么这不起作用吗?

【问题讨论】:

  • 您似乎没有对遍历进行任何操作。请参阅这些文档:docs.neo4j.org/chunked/stable/… 调用 traverse() 后,您会返回一个 Traverser 对象,但您不会遍历其结果(节点或关系或路径)。所以目前我没有做任何事情。
  • 我实际使用过,但没有复制这段代码。我编辑了我的帖子,感谢您指出这一点。

标签: java neo4j traversal


【解决方案1】:

我找到了解决问题的方法:

必须向 TraversalDescription 提供有关从起始节点而不是目标节点要做什么的信息。例如,如果我得到A - [:REL] -> B 并从A 开始,我必须指明关系的OUTGOING 方向。

这对我来说似乎不是用户友好的,因为它不像过滤器,我认为它是。

此外,我需要添加 .evaluator(Evaluators.excludeStartPosition()) 以从结果中排除初始节点。

我不知道解释是否足够清楚,但这是一个有效的代码:

/**
 * Find components of Caramel : tests that level 1 relationship works
 */
@Test
public void testCaramelContainsSugar() {
    try (Transaction ignored = graphDb.beginTx()) {

        Node n = null;
        TraversalDescription traversalDescription = graphDb.traversalDescription()
                .breadthFirst()
                .relationships(FoodRelationshipType.CONTAINS, Direction.OUTGOING)
                .evaluator(Evaluators.excludeStartPosition());

        Traverser traverser = traversalDescription.traverse(
                getSingleNode(LabelType.COOKED_MEAL, PropertyType.NAME.getName(), "Caramel")
        );

        List<Node> endNodes = new ArrayList<>();
        for (Path path : traverser) {
            endNodes.add(path.endNode());
        }

        Assert.assertTrue(endNodes.contains(getSingleNode(LabelType.RAW_MATERIAL, PropertyType.NAME.getName(), "Sugar")));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多