Neo4J - 将所有关系从一个节点复制到另一个节点(C#Wrapper)

时间:2016-04-07 15:43:09

标签: c# neo4j cypher neo4jclient

我目前正在努力解决一个问题,目前我还没有找到任何解决方法。 (我正在使用NEO4J C#库)

我需要将两个节点合并为第三个节点,并将这两个节点中的所有关系(Type& Properties)复制到我新创建的第三个节点:

(a:Label)-[r]-()
(b:Label)-[r2]-()
(c:Label)

我已经能够正确检索我的两个第一个节点&将它合并到数据库中创建的第三个节点,但我很难将所有关系从两个第一节点复制到第三个节点。

我尝试了几件事但没有成功,例如:

        using (GraphClient graphClient = GetGraphClient())
        {
            var inputString = string.Format("({0}:{1})-[r]->(n), ({2}:{3})", "a", typeof(Label).Name, "b", typeof(Label).Name);
            var query = graphClient.Cypher
                    .SendQueryOnMaster()
                    .Match(inputString)
                    .Where((Label a) => a.Id == from.Id)
                    .AndWhere((Label b) => b.Id == to.Id)
                    .Create("(b)-[r2:type(r)]->(n)");
            query.ExecuteWithoutResults();
        }

将所有关系从一个节点复制到另一个节点可能是人们可能遇到的用例:)

有什么方法可以让它发挥作用吗?

由于

2 个答案:

答案 0 :(得分:1)

Update, i've found a way to copy all relationships from one node to another using C# wrapper.

    internal static void DuplicateRelationships<T>(T from, T to) where T : IDataObject
    {
        string aVariable = "a";
        string bVariable = "b";
        string nVariable = "n";
        string relationVariable = "r";
        string newRelation = "r2";
        string relationsVariable = "rels";
        string relationPostCollectVariable = "rel";

        Guid fromId = from.Id;
        Guid toId = to.Id;

        foreach (string relation in CypherVerbs.GetAllVerbs())
        {
            using (GraphClient graphClient = GetGraphClient())
            {
                /*-[r]->*/
                graphClient.Cypher
                    .SendQueryOnMaster()
                    .Match(string.Format("({0}:{1})-[{2}:{3}]->({4}), ({5}:{6})", aVariable, from.GetType().Name, relationVariable, relation, nVariable, bVariable, to.GetType().Name))
                    .Where((T a) => a.Id == fromId)
                    .AndWhere((T b) => b.Id == toId)
                    .With(string.Format("COLLECT({0}) AS {1}, {2}, {3}, {4}", relationVariable, relationsVariable, aVariable, bVariable, nVariable))
                    .ForEach(string.Format("({0} in {1} | ", relationPostCollectVariable, relationsVariable))
                    .Create(string.Format("({0})-[{1}:{2}]->({3})", bVariable, newRelation, relation, nVariable))
                    .Set(string.Format("{0} += {1})", newRelation, relationPostCollectVariable))
                    .ExecuteWithoutResults();

                /*<-[r]-*/
                graphClient.Cypher
                    .SendQueryOnMaster()
                    .Match(string.Format("({0}:{1})<-[{2}:{3}]-({4}), ({5}:{6})", aVariable, from.GetType().Name, relationVariable, relation, nVariable, bVariable, to.GetType().Name))
                    .Where((T a) => a.Id == fromId)
                    .AndWhere((T b) => b.Id == toId)
                    .With(string.Format("COLLECT({0}) AS {1}, {2}, {3}, {4}", relationVariable, relationsVariable, aVariable, bVariable, nVariable))
                    .ForEach(string.Format("({0} IN {1} | ", relationPostCollectVariable, relationsVariable))
                    .Create(string.Format("({0})<-[{1}:{2}]-({3})", bVariable, newRelation, relation, nVariable))
                    .Set(string.Format("{0} += {1})", newRelation, relationPostCollectVariable))
                    .ExecuteWithoutResults();
            }
        }
    }

Here is the cypher code:

MATCH (a:Test {props1:"1"}), (b:Test {props3:"3"})
WITH a,b
MATCH (a)-[r:LINKED_TO]->(c)
WITH COLLECT(r) AS rels, a, b, c
FOREACH (rel in rels |
       CREATE (b)-[r:LINKED_TO]->(c)
       SET r+=rel
)

EDIT: Since Neo4j 3.0 you can use stored procedure to execute this more efficiently, Michael Hunger developed several template stored procedure including the copy all relationships from one node to another procedure.

Here is the link to the stored procedure repository: https://github.com/neo4j-contrib/neo4j-apoc-procedures

Here is the link to the documentation for graph refactoring: https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_graph_refactoring

答案 1 :(得分:0)

不幸的是Neo4j无法做到这一点,我想你已经在StackOverflow上找到了其他帖子:

如果您在编译时知道关系的标签,那么它是可能的,但它不适用于多个/动态标签类型。对不起,给你这个问题的答案并不是更好。