cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Improving query for moving nodes from one list structure to another

We have following structure where User is starting point and nodes with numbers are labeled Invitation where its value specify their property id .

I am looking for a way to create a query which moves node from list pointed by VALID_INVITATIONS relationship to another list pointed by INVALID_INVITATIONS. Moved node should be set first in new list.

I came up with working solution but because of lack of knowledge and experience in Cypher I kindly ask you, the community for help and improvements for it. As you will see there is a lot of imperative code "hacks" (CASE WHEN) instead of declarative as Cypher supposed to be. I would appreciate for all hints and advices

MATCH (u:User)
MATCH (u)-[:VALID_INVITATIONS|PREVIOUS*]->(current:Invitation{ id:3 })

//find (current) node's predecessor which might pointing on it through VALID_INVITATIONS or PREVIOUS relationships
OPTIONAL MATCH (u)-[oldValidRel:VALID_INVITATIONS]->(current)
OPTIONAL MATCH (predecessor:Invitation)-[oldPredecessorRel:PREVIOUS]->(current)
//find (current) node's subsequent node
OPTIONAL MATCH (current)-[oldSubsequentRel:PREVIOUS]->(subsequent:Invitation)

//first we re-create connections in list pointed by VALID_INVITATION relationship for consistency
WITH *, CASE subsequent WHEN NULL THEN ELSE [1] END AS hasSubsequent

//if (current) node is connected to (u) User we replace VALID_INVITATIONS relationship
FOREACH(_ IN CASE oldValidRel WHEN NULL THEN ELSE [1] END |
DELETE oldValidRel

//if (subsequent) node exist then we need to re-link it
FOREACH(_ IN hasSubsequent |
    MERGE (u)-[:VALID_INVITATIONS]->(subsequent)
    DELETE oldSubsequentRel
)

)

//following condition should be XOR with the one above (only one must be executed)
//if (current) node has another Invitation node as predecessor in list
FOREACH(_ IN CASE oldPredecessorRel WHEN NULL THEN ELSE [1] END |
DELETE oldPredecessorRel

//if (subsequent) node exist then we need to re-link it
FOREACH(_ IN hasSubsequent |
    MERGE (predecessor)-[:PREVIOUS]->(subsequent)
    DELETE oldSubsequentRel
)

)

WITH u, current

//now it is time to move (current) node to beginning of the list pointed by INVALID_INVITATIONS relationship
MERGE (u)-[:INVALID_INVITATIONS]->(current)
WITH u, current
//find obsolete oldRel:INVALID_INVITATIONS relationship
MATCH (current)<-[:INVALID_INVITATIONS]-(u)-[oldRel:INVALID_INVITATIONS]->(oldInv)
DELETE oldRel
//link (current) with previously "first" node in INVALID_INVITATIONS list
MERGE (current)-[:PREVIOUS]->(oldInv)

0 REPLIES 0