Neo4j/GraphQL - get the last node in a linked list in order to continue the linked list with newly created nodes

223 views Asked by At

I have a linked list of Posts in a Group. A Group has a FIRST_POST and then subsequent NEXT_POST relationships. The GraphQL typedef looks like this:

type Group {
    id: ID!
    name: String!
    membersList: [User] @relation(direction: IN, name: "MEMBER_OF")
    engagesIn: Conversation @relation(direction: OUT, name: "ENGAGES_IN")
    posts: [Post] @cypher(statement: """
        MATCH (g:Group {id: this.id})-[:FIRST_POST|NEXT_POST*]->(post:Post) 
        RETURN post
    """)
    createdAt: DateTime
    updatedAt: DateTime
}

The cypher query MATCH (g:Group {id: this.id})-[:FIRST_POST|NEXT_POST*]->(post:Post) RETURN post returns all of a specific Group's posts. I want to create a new Post and add it to the Group in my schema's typedef. Here's one stab at it that I know is not correct, but is where my current efforts are:

CreatePost(body: String!, userId: ID!): Post
    @cypher(
      statement: """
        MATCH (u:User {id: $userId})-[:MEMBER_OF]->(g:Group)-[:FIRST_POST|NEXT_POST*]->(lp:Post) return Last(collect(p))
        CREATE (p:Post { id: apoc.create.uuid(), body: $body, createdAt: datetime(), updatedAt: datetime() }) 
        WITH p, lp
        MATCH (u:User)
        WHERE u.id = $userId 
        CREATE (p)<-[:WROTE]-(u)
        CREATE (p)-[:NEXT_POST]->(lp)
        RETURN u, p
    """)

This is a custom mutation that accept post body and userId arguments. This line MATCH (u:User {id: $userId})-[:MEMBER_OF]->(g:Group)-[:FIRST_POST|NEXT_POST*]->(lp:Post) return Last(collect(p)) would return the last post, though I know I cannot return here and haven't successfully found a way to alias that MATCH. Ultimately I need to CREATE the NEXT_POST relationship off of the last NEXT_POST in that group with CREATE (p)-[:NEXT_POST]->(<LAST POST IN GROUP>). The first line also uses the userId to find the group as Users are MEMBER_OF only one Group and Posts belong to only one Group.

1

There are 1 answers

0
Matt Larsuma On

So, some confusion on my part. Someone else created the schema with FIRST_POST being the most recently created post rather than the first post created. Renaming it to NEWEST_POST, I can no do this:

MATCH (u:User {id: $userId})-[:MEMBER_OF]->(g:Group)-[rel:NEWEST_POST]->(previousNewestPost:Post)
DELETE rel
CREATE (p:Post { id: apoc.create.uuid(), body: 'test new post', createdAt: datetime(), updatedAt: datetime() }) 
WITH p, g, previousNewestPost
MATCH (u:User)
WHERE u.id = $userId 
CREATE (p)<-[:WROTE]-(u)
CREATE (p)<-[:NEWEST_POST]-(g)
CREATE (p)-[:NEXT_POST]->(previousNewestPost)
RETURN u, p

to create a new post and update the relationships accordingly.