我的问题是......给定两个节点,节点A和节点B,是否有一个密码查询,它从节点A中删除所有关系,并将它们连接到节点B, 以前连接到节点A的所有节点现在都连接到节点B?
我确定此类查询有很多用例,但我的用例是合并多个社交网络登录:
鉴于我有一个使用谷歌作为登录提供商的会员帐户(member1) 我有一个单独的会员帐户(member2)使用Facebook作为登录提供商 当member1尝试连接到member2用作登录提供程序的同一个facebook帐户时 并且member1请求合并(合并帐户) 并且member2确认合并 然后合并member1和member2的帐户 一名成员将继续使用谷歌和Facebook作为登录提供商。
执行此操作的密码查询是什么?
答案 0 :(得分:5)
编辑:现在有办法动态指定关系类型。因此,下面的解决方法仅限于具有相同类型且没有属性的关系。
让我们创建一些数据:
class Singleton {
static let sharedInstance: Singleton = {
let instance = Singleton()
// setup code
return instance
}()
}
我们现在有这样的数据:
现在我们想要"移动"从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
结果是:
我们基本上做的是:
答案 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();
}
}