Wolfgang-Schuetzelhofer / jcypher

Java access to Neo4J graph databases at multiple levels of abstraction
Apache License 2.0
86 stars 15 forks source link

How to move node to another node #50

Closed lchunleo closed 5 years ago

lchunleo commented 5 years ago

If I have a node A that has a relationship with node B, but wish to break the relationship and move node A to form relationship with node C , how can I do so ?

I try the do.delete and detach which delete the node and relationship. How can I.deletr the relationship without delete the node and join the relation to another node ? Thanks

Wolfgang-Schuetzelhofer commented 5 years ago

Hi, sorry for the late response, I have been out of my office for some time. For what you want to do, you best use the generic graph model. Below you find some sample code that shows how to do what you want to achieve. The most interesting part you will find at the end of the code. At the beginning you just find some initialization, sample graph creation and query to finally come to the point where you can remove and add relations.

public void remove_add_change_relations() {
        List<JcError> errors;
        GrNode keanu;
        GrRelation actsInMatrix1, actsInMatrix2;
        GrNode matrix1, matrix2;

        boolean create = true;
        if (create) {
            // create some sample graph
            Graph graph = Graph.create(dbAccess);

            matrix1 = graph.createNode();
            matrix1.addLabel("Movie");
            matrix1.addProperty("title", "The Matrix");
            matrix1.addProperty("year", "1999-03-31");

            matrix2 = graph.createNode();
            matrix2.addLabel("Movie");
            matrix2.addProperty("title", "The Matrix Reloaded");
            matrix2.addProperty("year", "2003-05-07");

            keanu = graph.createNode();
            keanu.addLabel("Actor");
            keanu.addProperty("name", "Keanu Reeves");

            actsInMatrix1 = graph.createRelation("ACTS_IN", keanu, matrix1);
            actsInMatrix1.addProperty("role", "Neo");

            errors = graph.store();
            if (!errors.isEmpty()) {
                printErrors(errors);
                return;
            }
            // end create
        }
        keanu = null;
        actsInMatrix1 = null;
        matrix1 = null;
        matrix2 = null;

        // read graph from db
        JcNode n = new JcNode("n");
        JcRelation rel = new JcRelation("rel");
        JcNode movs = new JcNode("movs");
        IClause[] clauses = new IClause[]{
                MATCH.node(n).label("Actor").relation(rel).type("ACTS_IN").node().label("Movie"),
                MATCH.node(movs).label("Movie"),
                RETURN.value(rel),
                RETURN.value(n),
                RETURN.value(movs)
        };
        JcQuery query = new JcQuery();
        query.setClauses(clauses);
        print(query, Format.PRETTY_1);
        JcQueryResult result = dbAccess.execute(query);
        if (result.hasErrors()) {
            printErrors(result);
            return;
        }
        keanu = result.resultOf(n).get(0);
        actsInMatrix1 = result.resultOf(rel).get(0);
        List<GrNode> movies = result.resultOf(movs);
        if (movies.get(0).getProperty("title").getValue().equals("The Matrix")) {
            matrix1 = movies.get(0);
            matrix2 = movies.get(1);
        } else {
            matrix1 = movies.get(1);
            matrix2 = movies.get(0);
        }

        // here you do the change of relations (remove, add)
        Graph graph = result.getGraph();
        actsInMatrix2 = graph.createRelation("ACTS_IN", keanu, matrix2);
        actsInMatrix2.addProperty("role", actsInMatrix1.getProperty("role"));
        actsInMatrix1.remove();

        // now you simply store all changes done to the graph
        errors = graph.store();
        if (!errors.isEmpty()) {
            printErrors(errors);
            return;
        }
    }

I hope that helps.

Best regards, Wolfgang