图的遍历

package com.fly.demo;

import org.neo4j.graphdb.*;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.graphdb.traversal.Traverser;
import org.neo4j.io.fs.FileUtils;

import java.io.File;
import java.io.IOException;

/**
 * 图的遍历
 */
public class Frient {
    // 关系类型
    public enum RelTypes implements RelationshipType {
        HOME_NODE,
        KNOWS,
        CO_WORKER
    }

    private static final File DB_PATH = new File("demo/neo4j-td");
    private GraphDatabaseService graphDb;
    // home节点id
    private long homeNodeId;

    public static void main(String...args) throws IOException {
        Frient matrix = new Frient();
        matrix.setUp();
        System.out.println(matrix.printFriends());
        System.out.println(matrix.printWorkers());
        matrix.shutdown();
    }

    public void setUp() throws IOException{
        FileUtils.deleteRecursively(DB_PATH);
        graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
        registerShutdownHook();
        createNodespace();
    }

    private Node getEndNode(Long id) {
        return graphDb.getNodeById(id)
                .getSingleRelationship(RelTypes.HOME_NODE, Direction.OUTGOING)
                .getEndNode();
    }

    public String printFriends(){
        try (Transaction tx = graphDb.beginTx()) {
            Node neoNode = getEndNode(homeNodeId);
            int numberOfFriends = 0;
            StringBuilder output = new StringBuilder(neoNode.getProperty("name") + "'s friends:\n");
            Traverser friendsTraverser = getFriends(neoNode);
            for (Path friendPath : friendsTraverser) {
                output.append("At depth ").append(friendPath.length()).append(" => ").append(friendPath.endNode()
                        .getProperty("name")).append("\n");
                numberOfFriends++;
            }
            output.append("Number of friends found: ").append(numberOfFriends).append("\n");
            return output.toString();
        }
    }

    public String printWorkers(){
        try (Transaction tx = graphDb.beginTx()){
            StringBuilder output = new StringBuilder("co-worker:\n");
            int number = 0;
            Traverser traverser = findWorker(getEndNode(homeNodeId));
            for (Path hackerPath : traverser) {
                output.append("At depth ").append(hackerPath.length()).append(" => ").append(hackerPath.endNode()
                        .getProperty("name")).append("\n");
                number++;
            }
            output.append("Number of co-worker found: ").append(number).append("\n");
            return output.toString();
        }
    }

    //广度优先
    private Traverser getFriends(final Node person) {
        TraversalDescription td = graphDb.traversalDescription()
                .breadthFirst() //设置使用广度优先遍历算法
                .relationships(RelTypes.KNOWS, Direction.OUTGOING) // 关系函数为KNOWS,同时设置单向查找方向
                .evaluator(Evaluators.excludeStartPosition()); // 设置评估函数,从开始节点查找
        return td.traverse(person);
    }

    //深度优先
    private Traverser getFriendsDepth(final Node person) {
        TraversalDescription td = graphDb.traversalDescription()
                .depthFirst()
                .relationships(RelTypes.KNOWS, Direction.OUTGOING)
                .evaluator(Evaluators.excludeStartPosition());
        return td.traverse(person);
    }

    private Traverser findWorker(final Node startNode) {
        TraversalDescription td = graphDb.traversalDescription()
                .depthFirst() // 使用深度优先遍历算法
                // 使用2个关系函数来查找路径
                .relationships(RelTypes.CO_WORKER, Direction.OUTGOING)
                .relationships(RelTypes.KNOWS, Direction.OUTGOING)
                // 查找最终节点的CO_WORKER关系
                .evaluator(Evaluators.includeWhereLastRelationshipTypeIs(RelTypes.CO_WORKER));
        return td.traverse(startNode);
    }

    public void createNodespace() {
        try (Transaction tx = graphDb.beginTx()) {
            Node home = graphDb.createNode();
            homeNodeId = home.getId();

            Node user = graphDb.createNode();
            user.setProperty("name", "User");

            home.createRelationshipTo(user, RelTypes.HOME_NODE);
            Node one = graphDb.createNode();
            one.setProperty("name", "One");

            user.createRelationshipTo(one, RelTypes.KNOWS);

            Node first = graphDb.createNode();
            first.setProperty("name", "First");

            user.createRelationshipTo(first, RelTypes.KNOWS);
            first.createRelationshipTo(one, RelTypes.KNOWS);

            Node two = graphDb.createNode();
            two.setProperty("name", "Two");

            one.createRelationshipTo(two, RelTypes.KNOWS);
            first.createRelationshipTo(two, RelTypes.KNOWS);

            Node three = graphDb.createNode();
            three.setProperty("name", "Three");

            two.createRelationshipTo(three, RelTypes.KNOWS);

            Node four = graphDb.createNode();
            four.setProperty("name", "Four");

            three.createRelationshipTo(four, RelTypes.CO_WORKER);

            tx.success();
        }
    }

    private void registerShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread(graphDb::shutdown));
    }

    public void shutdown() {
        graphDb.shutdown();
    }
}
posted @ 2022-03-29 08:38  fly_bk  阅读(29)  评论(0编辑  收藏  举报