Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j Cypher查询从一个节点获取所有关系,并将它们附加到另一个节点_Neo4j_Cypher - Fatal编程技术网

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

Neo4j Cypher查询从一个节点获取所有关系,并将它们附加到另一个节点,neo4j,cypher,Neo4j,Cypher,我的问题是。。给定两个节点,节点A和节点B,是否存在一个密码查询,该查询将删除节点A中的所有关系,并将它们附加到节点B, 所以以前连接到节点A的所有节点现在都连接到节点B 我相信这样的查询有很多用例,但我的用例是合并多个社交网络登录: 鉴于我有一个会员帐户(member1),使用谷歌作为登录提供商 我有一个单独的会员帐户(member2),使用facebook作为登录提供商 当member1尝试连接到member2用作登录提供商的同一facebook帐户时 和member1请求合并(合并帐户)

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

我相信这样的查询有很多用例,但我的用例是合并多个社交网络登录:

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


密码查询是如何做到这一点的?

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


让我们创建一些数据:

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

查询:

MATCH (n1:Node1)-[r:REL]->(target)
MATCH (n2:Node2)
CREATE (n2)-[:REL]->(target)
DELETE r
结果是:

我们基本上做的是:

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

下面是我使用的替代解决方案的代码。我很难让单元测试运行,但一旦它们被修复,我会在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();
    }
}
import org.neo4j.graphdb.Direction;
导入org.neo4j.graphdb.GraphDatabaseService;
导入org.neo4j.graphdb.Node;
导入org.neo4j.graphdb.Relationship;
导入org.neo4j.graphdb.Transaction;
导入org.neo4j.server.plugins.Description;
导入org.neo4j.server.plugins.Name;
导入org.neo4j.server.plugins.Parameter;
导入org.neo4j.server.plugins.PluginTarget;
导入org.neo4j.server.plugins.ServerPlugin;
导入org.neo4j.server.plugins.Source;
/**
*@作者约翰·德弗拉尔
*此插件将所有关系从一个节点传输到另一个节点,包括关系
*方向、类型和属性。
*可以使用命令从neo4j浏览器ui调用
*:POST/db/data/ext/TransferRelationships/graphdb/transfer_relationships{“sourceNode”:“/db/data/node/”,“destinationNode”:“/db/data/node/”}
*/
公共类TransferRelationships扩展了ServerPlugin{
@名称(“转让关系”)
@说明(“将所有关系从一个节点转移到另一个节点”)
@PluginTarget(GraphDatabaseService.class)
公共长transferNodes(@Source GraphDatabaseService graphDb,
@Description(“源节点”)@参数(name=“sourceNode”,optional=false)节点sourceNode,
@Description(“目标节点”)@参数(name=“destinationNode”,optional=false)节点destinationNode){
try(事务tx=graphDb.beginTx()){
//转移传出关系
Iterable outgoingRelationships=sourceNode.getRelationships(Direction.OUTGOING);
对于(关系:支出关系){
Node otherNode=relationship.getOtherNode(sourceNode);
Relationship newRelationship=destinationNode.createRelationshipTo(其他节点,Relationship.getType());
Iterable propertyKeys=relationship.getPropertyKeys();
对于(字符串键:propertyKeys){
对象属性=relationship.getProperty(键);
newRelationship.setProperty(键,属性);
}
delete();
}
//转移传入关系
Iterable incomingRelationships=sourceNode.getRelationships(Direction.INCOMING);
for(关系:收入关系){
Node otherNode=relationship.getOtherNode(sourceNode);
Relationship newRelationship=otherNode.createRelationshipTo(destinationNode,Relationship.getType());
Iterable propertyKeys=relationship.getPropertyKeys();
对于(字符串键:propertyKeys){
对象属性=relationship.getProperty(键);
newRelationship.setProperty(键,属性);
}
delete();
}
成功();
}
返回destinationNode.getId();
}
}

我知道这个线程很旧,但我在谷歌上搜索了同样的问题,没有找到StackOverflow的解决方案。就是这样

正如迈克尔告诉我的 你可以用

还有一些类似于:

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 *
MATCH(n2:Resource{name:'destination Resource'})
匹配(n:Resource{name:'source-Resource'})()
调用apoc.refactor.to(r,n2)生成输入,输出
调用apoc.refactor.from(r2,n2)将输入作为i,输出作为o
返回*

谢谢您的帮助。它非常接近我要找的东西。在我的例子中,关系可以是任何东西,所以数据更像。。。创建(n1:Node1)创建(n2:Node2)创建(target1:Target)创建(target2:Target)创建(target3:Target)创建(n1)-[:REL1]->(target1)创建(n1)-[:REL2]->(target2)创建(n1)-[:REL3]->(target3);我已经修改了我的问题,以便更清楚地说明这一点,并对你的答案进行了更新。我的答案已更新。TL;博士;-不可能动态地指定新的关系类型。这让我感觉不那么糟糕,因为我无法弄清楚它,而且我在任何情况下都从中学会了一些密码。谢谢你的回答。决定实现一个服务器端扩展,因为使用JavaAPI实现它很简单。您知道除了通过rest之外,是否还有其他方法可以调用服务器端扩展?塞弗就是我
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 *