首页 文章

Neo4j遍历API

提问于
浏览
0

我是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());
  }

它's like the query doesn' t使用遍历 relationships() 方法 . 知道为什么这不起作用吗?

1 回答

  • 1

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

    TraversalDescription必须提供有关如何处理 the starting node 的信息,而不是 the target node . 例如,如果我得到 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")));
        }
    }
    

相关问题