Cypher查询从一个节点获取所有关系,并将它们附加到另一个节点

时间:2015-09-17 11:03:28

标签: neo4j cypher

我的问题是......给定两个节点,节点A和节点B,是否有一个密码查询,它从节点A中删除所有关系,并将它们连接到节点B, 以前连接到节点A的所有节点现在都连接到节点B?

我确定此类查询有很多用例,但我的用例是合并多个社交网络登录:

鉴于我有一个使用谷歌作为登录提供商的会员帐户(member1) 我有一个单独的会员帐户(member2)使用Facebook作为登录提供商 当member1尝试连接到member2用作登录提供程序的同一个facebook帐户时 并且member1请求合并(合并帐户) 并且member2确认合并 然后合并member1和member2的帐户 一名成员将继续使用谷歌和Facebook作为登录提供商。

执行此操作的密码查询是什么?

3 个答案:

答案 0 :(得分:5)

编辑:现在有办法动态指定关系类型。因此,下面的解决方法仅限于具有相同类型且没有属性的关系。

让我们创建一些数据:

class Singleton {
    static let sharedInstance: Singleton = {
        let instance = Singleton()
        // setup code
        return instance
    }()
}

我们现在有这样的数据:

data

现在我们想要"移动"从CREATE (n1:Node1) CREATE (n2:Node2) CREATE (target1:Target) CREATE (target2:Target) CREATE (target3:Target) CREATE (n1)-[:REL]->(target1) CREATE (n1)-[:REL]->(target2) CREATE (n1)-[:REL]->(target3); Node1

的关系

查询:

Node2

结果是:

result

我们基本上做的是:

  • 从一条路上获取关系
  • 与其他节点建立关系
  • 删除原始节点的关系

答案 1 :(得分:2)

我知道这个线程很旧,但是我用同样的问题搜索了一下,但是在StackOverflow上找不到解决方案。所以就在这里。

正如迈克尔告诉我的here 您可以使用APOC functions :

apoc.refactor.to(relations, destination_node)
apoc.refactor.from(relations, destination_node)

具有类似

MATCH(n2:Resource {name: 'destionation-resource'})
MATCH(n:Resource {name:'source-resource'})<-[r]-()
OPTIONAL MATCH(n)-[r2]->()
CALL apoc.refactor.to(r, n2) YIELD input, output
CALL apoc.refactor.from(r2, n2) YIELD input AS i, output AS o
RETURN *

答案 2 :(得分:0)

我使用的替代解决方案的代码如下。我无法让单元测试运行但是一旦它们被修复,我将在github上发布一个迷你项目。

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.server.plugins.Description;
import org.neo4j.server.plugins.Name;
import org.neo4j.server.plugins.Parameter;
import org.neo4j.server.plugins.PluginTarget;
import org.neo4j.server.plugins.ServerPlugin;
import org.neo4j.server.plugins.Source;

/**
 * @author John Deverall
 * This plugin transfers all relationships from one node to another, including the relationships
 * direction, type and properties. 
 * Can be called from the neo4j browser ui with command
 * :POST /db/data/ext/TransferRelationships/graphdb/transfer_relationships {"sourceNode":"/db/data/node/<node_id>", "destinationNode":"/db/data/node/<node_id>"}
 */
public class TransferRelationships extends ServerPlugin {

    @Name("transfer_relationships")
    @Description("Transfer all relationships from one node to another")

    @PluginTarget(GraphDatabaseService.class)
    public Long transferNodes(@Source GraphDatabaseService graphDb,
            @Description("The source node") @Parameter(name = "sourceNode", optional = false) Node sourceNode,
            @Description("The destination node") @Parameter(name = "destinationNode", optional = false) Node destinationNode) {

        try (Transaction tx = graphDb.beginTx()) {
            // transfer outgoing relationships
            Iterable<Relationship> outgoingRelationships = sourceNode.getRelationships(Direction.OUTGOING);
            for (Relationship relationship : outgoingRelationships) {
                Node otherNode = relationship.getOtherNode(sourceNode);
                Relationship newRelationship = destinationNode.createRelationshipTo(otherNode, relationship.getType());

                Iterable<String> propertyKeys = relationship.getPropertyKeys();
                for (String key : propertyKeys) { 
                    Object property = relationship.getProperty(key);
                    newRelationship.setProperty(key, property);
                }

                relationship.delete();
            }

            // transfer incoming relationships
            Iterable<Relationship> incomingRelationships = sourceNode.getRelationships(Direction.INCOMING);
            for (Relationship relationship : incomingRelationships) {
                Node otherNode = relationship.getOtherNode(sourceNode);
                Relationship newRelationship = otherNode.createRelationshipTo(destinationNode, relationship.getType());

                Iterable<String> propertyKeys = relationship.getPropertyKeys();
                for (String key : propertyKeys) { 
                    Object property = relationship.getProperty(key);
                    newRelationship.setProperty(key, property);
                }

                relationship.delete();
            }
            tx.success();
        }
        return destinationNode.getId();
    }
}