Neo4j.rb : 在将一个节点替换为另一个节点之前转移所有关系
Neo4j.rb : transfer all relationships before replacing a node by another
我正在尝试将所有传入和传出关系(包括它们的属性)从一个节点转移到另一个节点,然后再删除第一个节点。他们都有相同的标签。
讨论从这里开始:
Neo4j Cypher : transfer all relationships before replacing a node by another
node_query = Neo4j::Session.query.match(old_node: {uuid: node1.uuid}).match(new_node: {uuid: node2.uuid})
types = node_query.match('node-[rel]-()').pluck('DISTINCT type(rel)')
types.each do |type|
node_query.match('old_node-[rel]->(other)').with(:old_node, :rel, :other).create("new_node-[new_rel]->other").set('new_rel = rel').exec
node_query.match('old_node<-[rel]-(other)').with(:old_node, :rel, :other).create("new_node<-[new_rel]-other").set('new_rel = rel').exec
end
当我尝试实施时出现此错误
new_rel not defined (line 1, column 160)
"MATCH
(old_node {uuid: "YYYY"}),
(new_node {uuid: "XXXX"}),
oldnode-[rel]->(other)
WITH old_node, rel, other SET new_rel = rel
CREATE new_node-[new_rel]->other" ^
我尝试了另一种方法,它只适用于 Neo4j::ActiveRel rels,因为对于其他人没有 to_node 属性。似乎它无论如何都不会复制关系属性:
relations = old_node.rels(dir: :outgoing)
relations.each do |rel|
if defined? rel.to_node
new_node.create_rel(rel.type, rel.to_node, rel.props)
end
end
relations = self.rels(dir: :incoming)
relations.each do |rel|
if defined? rel.from_node
rel.from_node.create_rel(rel.type, new_node, rel.props)
end
end
啊,既然我看到了错误,我想我知道原来的答案有什么问题了。我也会看看你的其他解决方案,但这是我将如何修复原始解决方案(通过添加一个中断使 SET
在 CREATE
之后出现):
# Assuming node already loaded
node_query = Neo4j::Session.query.match(node: {neo_id: node.neo_id}, new_node: {neo_id: new_node.neo_id})
types = node_query.match('node-[rel]-()').pluck('DISTINCT type(rel)')
types.each do |type|
node_query.match('node-[rel:#{type}]->(other)').
where('other <> new_node').
with(:node, :new_node, :rel, :other).
create("new_node-[new_rel:#{type}]->other").
break.set('new_rel = rel').exec
node_query.match('node<-[rel:#{type}]-(other)').
where('other <> new_node').
with(:node, :new_node, :rel, :other).
create("new_node<-[new_rel:#{type}]-other").
break.set('new_rel = rel').exec
end
至于你的其他解决方案,我不太熟悉 rels
方法(我似乎找不到它),但我想它是 returning CypherRelationship
或 ActiveRel
个对象。我真的有点惊讶它只有在你定义 ActiveRel
模型时才有效,因为如果没有定义它应该 return CypherRelationship
个对象。
我对你的问题的猜测是,你可能需要使用 start_node
和 end_node
而不是 from_node
和 to_node
。我们或许应该将其标准化...
编辑:我正在编辑它以添加 Neo4j::Server::CypherRelationship,当它不是 ActiveRel 时 returned。没有 start_node 也没有来自节点 :
{
"session": {
"connection": {
"parallel_manager": null,
"headers": {
"Content-Type": "application/json",
"User-Agent": "neo4j-gem/4.1.2 (https://github.com/neo4jrb/neo4j)",
"Authorization": "Basic realm=\"Neo4j\" OjdhYTUxNTcyYzBmMzBkYTMyNmY0NWQwMDc4ZTRlY2Rk"
},
"params": {},
"options": {
"params_encoder": null,
"proxy": null,
"bind": null,
"timeout": null,
"open_timeout": null,
"boundary": null,
"oauth": null
},
"ssl": {
"verify": null,
"ca_file": null,
"ca_path": null,
"verify_mode": null,
"cert_store": null,
"client_cert": null,
"client_key": null,
"certificate": null,
"private_key": null,
"verify_depth": null,
"version": null
},
"default_parallel_manager": null,
"builder": {
"handlers": [
{
"name": "Faraday::Request::BasicAuthentication",
"args": [
"neo4j",
"hroads"
],
"block": null
},
{
"name": "FaradayMiddleware::EncodeJson",
"args": [],
"block": null
},
{
"name": "FaradayMiddleware::ParseJson",
"args": [
{
"content_type": "application/json"
}
],
"block": null
},
{
"name": "Faraday::Adapter::NetHttpPersistent",
"args": [],
"block": null
}
],
"app": {
"header_value": "Basic bmVvNGo6aHJvYWRz",
"app": {
"app": {
"app": {
"app": {}
},
"options": {
"content_type": "application/json"
},
"content_types": [
"application/json"
]
}
}
}
},
"url_prefix": {
"scheme": "http",
"user": null,
"password": null,
"host": null,
"port": 80,
"path": "/",
"query": null,
"opaque": null,
"registry": null,
"fragment": null,
"parser": null
},
"proxy": null
},
"auth": {
"url": "http://localhost:7474",
"connection": {
"parallel_manager": null,
"headers": {
"Content-Type": "application/json",
"User-Agent": "neo4j-gem/4.1.2 (https://github.com/neo4jrb/neo4j)",
"Authorization": "Basic realm=\"Neo4j\" OjdhYTUxNTcyYzBmMzBkYTMyNmY0NWQwMDc4ZTRlY2Rk"
},
"params": {},
"options": {
"params_encoder": null,
"proxy": null,
"bind": null,
"timeout": null,
"open_timeout": null,
"boundary": null,
"oauth": null
},
"ssl": {
"verify": null,
"ca_file": null,
"ca_path": null,
"verify_mode": null,
"cert_store": null,
"client_cert": null,
"client_key": null,
"certificate": null,
"private_key": null,
"verify_depth": null,
"version": null
},
"default_parallel_manager": null,
"builder": {
"handlers": [
{
"name": "Faraday::Request::BasicAuthentication",
"args": [
"neo4j",
"hroads"
],
"block": null
},
{
"name": "FaradayMiddleware::EncodeJson",
"args": [],
"block": null
},
{
"name": "FaradayMiddleware::ParseJson",
"args": [
{
"content_type": "application/json"
}
],
"block": null
},
{
"name": "Faraday::Adapter::NetHttpPersistent",
"args": [],
"block": null
}
],
"app": {
"header_value": "Basic bmVvNGo6aHJvYWRz",
"app": {
"app": {
"app": {
"app": {}
},
"options": {
"content_type": "application/json"
},
"content_types": [
"application/json"
]
}
}
}
},
"url_prefix": {
"scheme": "http",
"user": null,
"password": null,
"host": null,
"port": 80,
"path": "/",
"query": null,
"opaque": null,
"registry": null,
"fragment": null,
"parser": null
},
"proxy": null
},
"params": {
"basic_auth": {
"username": "neo4j",
"password": "hroads"
}
},
"token": "7aa51572c0f30da326f45d0078e4ecdd"
},
"resource_url": "http://localhost:7474/db/data/",
"resource_data": {
"extensions": {},
"node": "http://localhost:7474/db/data/node",
"node_index": "http://localhost:7474/db/data/index/node",
"relationship_index": "http://localhost:7474/db/data/index/relationship",
"extensions_info": "http://localhost:7474/db/data/ext",
"relationship_types": "http://localhost:7474/db/data/relationship/types",
"batch": "http://localhost:7474/db/data/batch",
"cypher": "http://localhost:7474/db/data/cypher",
"indexes": "http://localhost:7474/db/data/schema/index",
"constraints": "http://localhost:7474/db/data/schema/constraint",
"transaction": "http://localhost:7474/db/data/transaction",
"node_labels": "http://localhost:7474/db/data/labels",
"neo4j_version": "2.2.0-M02"
}
},
"response_hash": {
"extensions": {},
"metadata": {
"id": 2000,
"type": "LEAD_TO"
},
"data": {
"created_at": 1422832907
},
"property": "http://localhost:7474/db/data/relationship/2000/properties/{key}",
"start": "http://localhost:7474/db/data/node/1266",
"self": "http://localhost:7474/db/data/relationship/2000",
"end": "http://localhost:7474/db/data/node/1264",
"type": "LEAD_TO",
"properties": "http://localhost:7474/db/data/relationship/2000/properties",
"id": 2000
},
"rel_type": "LEAD_TO",
"props": {
"created_at": 1422832907
},
"start_node_neo_id": 1266,
"end_node_neo_id": 1264,
"id": 2000
}
我正在尝试将所有传入和传出关系(包括它们的属性)从一个节点转移到另一个节点,然后再删除第一个节点。他们都有相同的标签。
讨论从这里开始: Neo4j Cypher : transfer all relationships before replacing a node by another
node_query = Neo4j::Session.query.match(old_node: {uuid: node1.uuid}).match(new_node: {uuid: node2.uuid})
types = node_query.match('node-[rel]-()').pluck('DISTINCT type(rel)')
types.each do |type|
node_query.match('old_node-[rel]->(other)').with(:old_node, :rel, :other).create("new_node-[new_rel]->other").set('new_rel = rel').exec
node_query.match('old_node<-[rel]-(other)').with(:old_node, :rel, :other).create("new_node<-[new_rel]-other").set('new_rel = rel').exec
end
当我尝试实施时出现此错误
new_rel not defined (line 1, column 160)
"MATCH
(old_node {uuid: "YYYY"}),
(new_node {uuid: "XXXX"}),
oldnode-[rel]->(other)
WITH old_node, rel, other SET new_rel = rel
CREATE new_node-[new_rel]->other" ^
我尝试了另一种方法,它只适用于 Neo4j::ActiveRel rels,因为对于其他人没有 to_node 属性。似乎它无论如何都不会复制关系属性:
relations = old_node.rels(dir: :outgoing)
relations.each do |rel|
if defined? rel.to_node
new_node.create_rel(rel.type, rel.to_node, rel.props)
end
end
relations = self.rels(dir: :incoming)
relations.each do |rel|
if defined? rel.from_node
rel.from_node.create_rel(rel.type, new_node, rel.props)
end
end
啊,既然我看到了错误,我想我知道原来的答案有什么问题了。我也会看看你的其他解决方案,但这是我将如何修复原始解决方案(通过添加一个中断使 SET
在 CREATE
之后出现):
# Assuming node already loaded
node_query = Neo4j::Session.query.match(node: {neo_id: node.neo_id}, new_node: {neo_id: new_node.neo_id})
types = node_query.match('node-[rel]-()').pluck('DISTINCT type(rel)')
types.each do |type|
node_query.match('node-[rel:#{type}]->(other)').
where('other <> new_node').
with(:node, :new_node, :rel, :other).
create("new_node-[new_rel:#{type}]->other").
break.set('new_rel = rel').exec
node_query.match('node<-[rel:#{type}]-(other)').
where('other <> new_node').
with(:node, :new_node, :rel, :other).
create("new_node<-[new_rel:#{type}]-other").
break.set('new_rel = rel').exec
end
至于你的其他解决方案,我不太熟悉 rels
方法(我似乎找不到它),但我想它是 returning CypherRelationship
或 ActiveRel
个对象。我真的有点惊讶它只有在你定义 ActiveRel
模型时才有效,因为如果没有定义它应该 return CypherRelationship
个对象。
我对你的问题的猜测是,你可能需要使用 start_node
和 end_node
而不是 from_node
和 to_node
。我们或许应该将其标准化...
编辑:我正在编辑它以添加 Neo4j::Server::CypherRelationship,当它不是 ActiveRel 时 returned。没有 start_node 也没有来自节点 :
{
"session": {
"connection": {
"parallel_manager": null,
"headers": {
"Content-Type": "application/json",
"User-Agent": "neo4j-gem/4.1.2 (https://github.com/neo4jrb/neo4j)",
"Authorization": "Basic realm=\"Neo4j\" OjdhYTUxNTcyYzBmMzBkYTMyNmY0NWQwMDc4ZTRlY2Rk"
},
"params": {},
"options": {
"params_encoder": null,
"proxy": null,
"bind": null,
"timeout": null,
"open_timeout": null,
"boundary": null,
"oauth": null
},
"ssl": {
"verify": null,
"ca_file": null,
"ca_path": null,
"verify_mode": null,
"cert_store": null,
"client_cert": null,
"client_key": null,
"certificate": null,
"private_key": null,
"verify_depth": null,
"version": null
},
"default_parallel_manager": null,
"builder": {
"handlers": [
{
"name": "Faraday::Request::BasicAuthentication",
"args": [
"neo4j",
"hroads"
],
"block": null
},
{
"name": "FaradayMiddleware::EncodeJson",
"args": [],
"block": null
},
{
"name": "FaradayMiddleware::ParseJson",
"args": [
{
"content_type": "application/json"
}
],
"block": null
},
{
"name": "Faraday::Adapter::NetHttpPersistent",
"args": [],
"block": null
}
],
"app": {
"header_value": "Basic bmVvNGo6aHJvYWRz",
"app": {
"app": {
"app": {
"app": {}
},
"options": {
"content_type": "application/json"
},
"content_types": [
"application/json"
]
}
}
}
},
"url_prefix": {
"scheme": "http",
"user": null,
"password": null,
"host": null,
"port": 80,
"path": "/",
"query": null,
"opaque": null,
"registry": null,
"fragment": null,
"parser": null
},
"proxy": null
},
"auth": {
"url": "http://localhost:7474",
"connection": {
"parallel_manager": null,
"headers": {
"Content-Type": "application/json",
"User-Agent": "neo4j-gem/4.1.2 (https://github.com/neo4jrb/neo4j)",
"Authorization": "Basic realm=\"Neo4j\" OjdhYTUxNTcyYzBmMzBkYTMyNmY0NWQwMDc4ZTRlY2Rk"
},
"params": {},
"options": {
"params_encoder": null,
"proxy": null,
"bind": null,
"timeout": null,
"open_timeout": null,
"boundary": null,
"oauth": null
},
"ssl": {
"verify": null,
"ca_file": null,
"ca_path": null,
"verify_mode": null,
"cert_store": null,
"client_cert": null,
"client_key": null,
"certificate": null,
"private_key": null,
"verify_depth": null,
"version": null
},
"default_parallel_manager": null,
"builder": {
"handlers": [
{
"name": "Faraday::Request::BasicAuthentication",
"args": [
"neo4j",
"hroads"
],
"block": null
},
{
"name": "FaradayMiddleware::EncodeJson",
"args": [],
"block": null
},
{
"name": "FaradayMiddleware::ParseJson",
"args": [
{
"content_type": "application/json"
}
],
"block": null
},
{
"name": "Faraday::Adapter::NetHttpPersistent",
"args": [],
"block": null
}
],
"app": {
"header_value": "Basic bmVvNGo6aHJvYWRz",
"app": {
"app": {
"app": {
"app": {}
},
"options": {
"content_type": "application/json"
},
"content_types": [
"application/json"
]
}
}
}
},
"url_prefix": {
"scheme": "http",
"user": null,
"password": null,
"host": null,
"port": 80,
"path": "/",
"query": null,
"opaque": null,
"registry": null,
"fragment": null,
"parser": null
},
"proxy": null
},
"params": {
"basic_auth": {
"username": "neo4j",
"password": "hroads"
}
},
"token": "7aa51572c0f30da326f45d0078e4ecdd"
},
"resource_url": "http://localhost:7474/db/data/",
"resource_data": {
"extensions": {},
"node": "http://localhost:7474/db/data/node",
"node_index": "http://localhost:7474/db/data/index/node",
"relationship_index": "http://localhost:7474/db/data/index/relationship",
"extensions_info": "http://localhost:7474/db/data/ext",
"relationship_types": "http://localhost:7474/db/data/relationship/types",
"batch": "http://localhost:7474/db/data/batch",
"cypher": "http://localhost:7474/db/data/cypher",
"indexes": "http://localhost:7474/db/data/schema/index",
"constraints": "http://localhost:7474/db/data/schema/constraint",
"transaction": "http://localhost:7474/db/data/transaction",
"node_labels": "http://localhost:7474/db/data/labels",
"neo4j_version": "2.2.0-M02"
}
},
"response_hash": {
"extensions": {},
"metadata": {
"id": 2000,
"type": "LEAD_TO"
},
"data": {
"created_at": 1422832907
},
"property": "http://localhost:7474/db/data/relationship/2000/properties/{key}",
"start": "http://localhost:7474/db/data/node/1266",
"self": "http://localhost:7474/db/data/relationship/2000",
"end": "http://localhost:7474/db/data/node/1264",
"type": "LEAD_TO",
"properties": "http://localhost:7474/db/data/relationship/2000/properties",
"id": 2000
},
"rel_type": "LEAD_TO",
"props": {
"created_at": 1422832907
},
"start_node_neo_id": 1266,
"end_node_neo_id": 1264,
"id": 2000
}