1

I'm trying to transfert all ingoing and outgoing relationships (including their properties) from a node to another, before deleting the first one. they both have the same label.

The discussion started here : 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

When i tried to implement that i get this error

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" ^

I tried another way which works only for the Neo4j::ActiveRel rels, beacause for the others there's no to_node property. It seems that it doesn't copy the relationship properties anyway :

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
Community
  • 1
  • 1
armedwing
  • 113
  • 1
  • 10

2 Answers2

2

Ah, now that I see the error I think I know what was wrong with the original answer. I'll look at your other solution too, but here is how I would fix the original (by adding a break to make the SET come after the 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
Brian Underwood
  • 10,746
  • 1
  • 22
  • 34
  • thanks Brian. now i've this error : `A single relationship type must be specified for CREATE (line 1, column 171)` – armedwing Feb 02 '15 at 10:08
  • ok, your query works but it is designed to create another relationship between the same nodes. if i replace `node-[new_rel:#{type}]->other` with `newnode-[new_rel:#{type}]->other` it doesn't create anything. do you see what i mean (look at my code on top of the page) ? – armedwing Feb 02 '15 at 18:26
  • ;) perfect ! sorry for being so slow... i was doing the match in the first query... how would you exclude the rel between the node and the new node (in case it exists) so that the newnode doesn't end up with a relation to itself ? something like `.not(:node, {neo_id: new_node.neo_id})` ? – armedwing Feb 03 '15 at 09:42
1

As to your other solution, I'm not too familiar with the rels method (and I can't seem to find it), but I imagine it's returning either CypherRelationship or ActiveRel objects. I'm actually a bit surprised it only works if you define ActiveRel models, because it should return CypherRelationship objects if one isn't defined.

My guess as to your problem, though, is that you probably need to use start_node and end_node instead of from_node and to_node. We should probably standardize that...


EDIT : i'm editing this to add the Neo4j::Server::CypherRelationship that is returned when it's not an ActiveRel. there's no start_node nor from 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

}

armedwing
  • 113
  • 1
  • 10
Brian Underwood
  • 10,746
  • 1
  • 22
  • 34