Neo4j Cypher查询从一个节点获取所有关系,并将它们附加到另一个节点
我的问题是。。给定两个节点,节点A和节点B,是否存在一个密码查询,该查询将删除节点A中的所有关系,并将它们附加到节点B, 所以以前连接到节点A的所有节点现在都连接到节点B 我相信这样的查询有很多用例,但我的用例是合并多个社交网络登录: 鉴于我有一个会员帐户(member1),使用谷歌作为登录提供商 我有一个单独的会员帐户(member2),使用facebook作为登录提供商 当member1尝试连接到member2用作登录提供商的同一facebook帐户时 和member1请求合并(合并帐户) 成员2确认合并 然后,member1和member2的帐户将合并 还有一名会员将继续使用谷歌和facebook作为登录提供商Neo4j Cypher查询从一个节点获取所有关系,并将它们附加到另一个节点,neo4j,cypher,Neo4j,Cypher,我的问题是。。给定两个节点,节点A和节点B,是否存在一个密码查询,该查询将删除节点A中的所有关系,并将它们附加到节点B, 所以以前连接到节点A的所有节点现在都连接到节点B 我相信这样的查询有很多用例,但我的用例是合并多个社交网络登录: 鉴于我有一个会员帐户(member1),使用谷歌作为登录提供商 我有一个单独的会员帐户(member2),使用facebook作为登录提供商 当member1尝试连接到member2用作登录提供商的同一facebook帐户时 和member1请求合并(合并帐户)
密码查询是如何做到这一点的?编辑:现在可以动态指定关系类型。因此,下面的解决方法仅限于具有相同类型且没有属性的关系
让我们创建一些数据:
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
结果是:
我们基本上做的是:
- 从一条路径获取关系
- 创建与其他节点的关系
- 从原始节点删除关系
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 *