Neo4j3.5学习笔记——Traversal遍历之黑客帝国

跟着官网代码学习.jpg–jdk 1.8.0 & neo4j 3.5
https://neo4j.com/docs/java-reference/current/java-embedded/

目标:查找朋友以及朋友的朋友 + 找最终的Hacker

  • 待实现节点关系图:在这里插入图片描述 1. 节点以及关系建立 实现代码:
    1)matrixNodeID = matrix.getId();
    matrixNodeI是一个private long变量->仅用于存放Node matrix的ID,不是每新建一个Node都要更新一下;
    2)Relationship rel2 = morpheus.createRelationshipTo(cypher, RelTypes.KNOWS); rel.setProperty("disclosure","public");
    给relationship添加属性的方法;
    3)Relationship rel2 = morpheus.createRelationshipTo(cypher, RelTypes.KNOWS); rel.setProperty("disclosure","public");
    给relationship添加属性的方法;
private void createNodespace() {
	try (Transaction tx = graphDb.beginTx()) {
        Node matrix = graphDb.createNode();
        matrixNodeID = matrix.getId(); //matrixNodeID是一个private long变量->仅用于存放Node matrix的ID
        Node thomas = graphDb.createNode();

        thomas.setProperty("name", "Thomas Anderson");
        thomas.setProperty("age", "29");
        matrix.createRelationshipTo(thomas, RelTypes.NEO_NODE);

        Node trinity = graphDb.createNode();
        trinity.setProperty("name", "Trinity");
        Relationship rel = thomas.createRelationshipTo(trinity, RelTypes.KNOWS);
        rel.setProperty("age", "3 days");

        Node morpheus = graphDb.createNode();
        morpheus.setProperty("name", "Morpheus");
        morpheus.setProperty("occupation", "Total badass");
        morpheus.setProperty("rank", "Captain");
        Relationship rel1 = morpheus.createRelationshipTo(trinity, RelTypes.KNOWS);
        rel.setProperty("age", "12 years");
        thomas.createRelationshipTo(morpheus, RelTypes.KNOWS);

        Node cypher = graphDb.createNode();
        cypher.setProperty("last name", "Reagan");
        cypher.setProperty("name", "Cypher");
        Relationship rel2 = morpheus.createRelationshipTo(cypher, RelTypes.KNOWS);
        rel.setProperty("disclosure", "public");

        Node smith = graphDb.createNode();
        smith.setProperty("language", "C++");
        smith.setProperty("name", "Agent Smith");
        smith.setProperty("version", "1.0b");
        Relationship rel3 = cypher.createRelationshipTo(smith, RelTypes.KNOWS);
        rel3.setProperty("age", "6 months");
        rel3.setProperty("disclosure", "secret");

        Node architect = graphDb.createNode();
        architect.setProperty("name", "The Architect");
        smith.createRelationshipTo(architect, RelTypes.CODED_BY);

        tx.success();
	}
}

2. 找到朋友以及朋友的朋友 实现代码:

  • 图的遍历:获取到与图中节点之间的关系相关的信息。进行遍历之前,需要对遍历的方式进行描述。描述信息由以下要素组成:
    遍历的路径:通常用关系的类型和方向来表示;
    遍历的顺序:深度优先depthFirst & 广度优先breadthFirst
    遍历的唯一性:可以指定在整个遍历中是否允许经过重复的节点、关系或路径;
    遍历过程的决策器:用来在遍历过程中判断是否继续进行遍历,以及遍历过程的返回结果;
    起始节点:遍历过程的起点。
  • 遍历方式的描述信息由 org.neo4j.graphdb.traversal.TraversalDescription 接口来表示。通过 TraversalDescription 接口的方法可以描述上面介绍的遍历过程的不同要素。
  • 注意要点:
    1)matrixNodeID = matrix.getId();
    matrixNodeI是一个private long变量->仅用于存放Node matrix的ID,不是每新建一个Node都要更新一下;
    2)Traverser friendsTraverser = getFriends(neoNode);
    Traverser类型:Implementing this interface allows an object to be the target of the “for-each loop” statement.
    3)具体的遍历描述方法:通过Traverser类的description方法创建了一个默认的遍历描述对象,通过breadthFirst设置为广度优先的遍历方式,relationships方法设置遍历时经过的关系的类型;比较复杂的表示遍历过程决策器的evaluator方法,该方法的参数是org.neo4j.graphdb.traversal.Evaluator接口的实现对象,Evaluator接口只有一个方法evaluate,evaluate方法的参数是Path接口的实现对象,表示当前的遍历路径,而evaluate方法的返回值是枚举类型org.neo4j.graphdb.traversal.Evaluation,表示不同的处理策略。处理策略由两个方面组成:是否包含当前节点&是否继续进行遍历。Evaluator 接口的实现者需要根据遍历时的当前路径,做出相应的决策,返回适当的 Evaluation 类型的值。类org.neo4j.graphdb.traversal.Evaluators提供了一些实用的方法来创建常用的 Evaluator 接口的实现对象。示例代码中使用了 Evaluators 类的一个方法Evaluators.excludeStartPosition(),包含start节点;另一个方法Evaluators.pruneWhereLastRelationshipTypeIs返回的 Evaluator 接口的实现对象会根据遍历路径的最后一个关系的类型来进行判断,如果关系类型满足给定的条件,则不再继续进行遍历。
  • 感觉有点难以理解,其实就是设置个遍历方式+遍历经过的关系类型+evaluator(Evaluators.是否包含当前节点&是否继续进行遍历),返回的是Traverse类型。
private Traverser getFriends(final Node person) {
    TraversalDescription td = graphDb.traversalDescription()
            .breadthFirst()
            .relationships(RelTypes.KNOWS, Direction.OUTGOING)
            .evaluator(Evaluators.excludeStartPosition());
    return td.traverse(person);
}

  • 通过NodeID找节点:之前存过matrix的NodeIDmatrixNodeID = matrix.getId();,通过graphDb.getNodeById(NodeID)找到matrix节点,再通过找关系类型的endNode来找到NeoNode。
private Node getNeoNode() {
    return graphDb.getNodeById(matrixNodeID)
            .getSingleRelationship(RelTypes.NEO_NODE, Direction.OUTGOING)
            .getEndNode();
}

  • 找朋友的朋友:起始节点neoNode和遍历friendsTraverser。for (Path friendPath : friendsTraverser) {}得到遍历中的Path路径,用path.endNode()找到节点,再.getProperty()得到节点的属性。
  • String类型是可以+的
public String printNeoFriends() {
    try ( Transaction tx = graphDb.beginTx()) {
        Node neoNode = getNeoNode();
        int numOfFriends = 0;
        String output = neoNode.getProperty("name") + "'s friends:\n";
        Traverser friendsTraverser = getFriends(neoNode);
        for (Path friendPath : friendsTraverser) {
            output += "At depth" + friendPath.length() + "=>"
                    +friendPath.endNode()
                    .getProperty("name") + "\n";
            numOfFriends++;
        }
        output += "Number of friends found" + numOfFriends + "\n";
        return output;
    }
}

3. 找最终的Hacker 实现代码:

  • 示例代码中使用了 Evaluators 类的一个方法Evaluators.excludeStartPosition(),包含start节点;另一个方法Evaluators.pruneWhereLastRelationshipTypeIs返回的 Evaluator 接口的实现对象会根据遍历路径的最后一个关系的类型来进行判断,如果关系类型满足给定的条件,则不再继续进行遍历。
public String printMatrixHackers() {
        try (Transaction tx = graphDb.beginTx()) {
            String output = "Hackers:\n";
            int numOfHackers = 0;
            Traverser traverser = findHackers(getNeoNode());
            for(Path hackerPath : traverser) {
                output += "At depth " + hackerPath.length() + "=>"
                        + hackerPath.endNode()
                        .getProperty("name") + "\n";
                numOfHackers++;
            }
            output += "Number of hackers found: " + numOfHackers + "\n";
            return output;
        }
    }

    private Traverser findHackers(final Node startNode) {
            TraversalDescription td = graphDb.traversalDescription()
                    .breadthFirst()
                    .relationships(RelTypes.CODED_BY, Direction.OUTGOING)
                    .relationships(RelTypes.KNOWS, Direction.OUTGOING)
                    .evaluator(Evaluators
                    .includeWhereLastRelationshipTypeIs(RelTypes.CODED_BY));
            return td.traverse(startNode);
    }

4. 具体代码: https://github.com/Amy996bbq/Neo4j/blob/master/learn/NewMatrix_1.java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值