neo4j / graphql

A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations.
https://neo4j.com/docs/graphql-manual/current/
Apache License 2.0
495 stars 147 forks source link

How can I add a property to a new node when using onConnectOrCreate in Neo4j GraphQL? #1068

Closed dan-fein closed 2 years ago

dan-fein commented 2 years ago

I'm using Neo4j's GraphQL library, trying to use connectOrCreate for a new Image, which is defined like this:

type Image {
    id: ID! @id(autogenerate: true),
    url: String! @unique, 
    creator: User! @relationship(type: "CREATED_BY", direction: OUT),
}

And based on the documentation on the Neo4j website, I should be able to say if a node with the url field is not found, then create one and set some properties. Like this:

mutation NEW_POST {
  createPosts(input: { images: { 
    connectOrCreate: [{ 
      where: { node: { url: "https://picsum.photos/600" }}
      onCreate: { where: { node: { creator: { node: { id: "userId"}}}}},
    }]}}){
  posts {
    id
    }
  }
}

However, for the onCreate Field Input, my only options are id and url. Meaning, I can't actually add the creator property like I do here.

"Field \"creator\" is not defined by type \"ImageOnCreateInput\".",

Do you think this is intended, or any idea where I should look for guidance? I'm looking at this documentation: https://neo4j.com/docs/graphql-manual/current/mutations/create/ which shows onCreate: { node: { title: "Forrest Gump" } } achieving what I hope to achieve.

enter image description here

neo4j-team-graphql commented 2 years ago

Many thanks for raising this bug report @danielfein. :bug: We will now attempt to reproduce the bug based on the steps you have provided.

Please ensure that you've provided the necessary information for a minimal reproduction, including but not limited to:

If you have a support agreement with Neo4j, please link this GitHub issue to a new or existing Zendesk ticket.

Thanks again! :pray:

tbwiss commented 2 years ago

Hi @danielfein! Thanks for reaching out! If the node with the url https://picsum.photos/600 does not exist, a new node node with the information provided in the onCreate part of the mutation will be created. This "onCreate" node (with ImageOnCreateInput) will automatically connect the node that is specified as the "anchor". See my comments in the slightly modified mutation that you provided:

mutation NEW_POST {
  createPosts(
    input: {
      id: "userId"     // Note this 'id' here. This is the 'anchor' node.
      images: {
        connectOrCreate: [
          {
            where: { node: { url: "https://picsum.photos/600" } }
            onCreate: { node: { name: "the name" } }       // If the node with "https://picsum.photos/600" does not exist, this will create a Post with "the name" and also connect it to the anchor node with id "userId".
          }
        ]
      }
    }
  ) {
    posts {
      id
    }
  }
}

You can experiment and play with the typeDefs and mutation provided in the documentation (https://neo4j.com/docs/graphql-manual/current/mutations/create/#_connectorcreate_relationships) to see how the connectOrCreate relationship mutation is operating.

As a tip, you can use the Apollo Server Sandbox to create your queries/mutations.

Hope this information helps, otherwise feel free to reach out again!

dan-fein commented 2 years ago

Hi @angrykoala and @darrellwarde sorry, I appreciate your response but this actually seems more like a bug. The only noticeable difference between your query and mine appears to be the use of the anchor ID for the new post and then the "where" that I shouldn't have had in my onCreate but it looks like even without it it's till not working.

If you notice my schema above for ImageOnCreateInput, I only have id and url available. So in addition of connecting the Image node back to the new Post node, I also want to have it connect to a User ID, and eventually have other properties on Image other than just id, url, and creator, but those are not showing up for me to add via onCreate

This is the error I got, despite creator being a property of Image.

Variable \"$images\" got invalid value { creator: { node: [Object] } } at \"images.connectOrCreate[0].onCreate.node\"; Field \"creator\" is not defined by type \"ImageOnCreateInput\".",

Any idea? I doubt this is the expected behavior, as one should be able to create a full node onCreate rather than partial ones like available now.

dan-fein commented 2 years ago

Can somebody please reopen this? Also here is the query in context:

Screen Shot 2022-03-01 at 8 27 29 AM
darrellwarde commented 2 years ago

Hey @danielfein, nested operations are currently not supported by connectOrCreate, hence why you cannot specify the creator field in the onCreate object. Can you please raise a feature request for this if you would like to see it implemented? Thanks!

dan-fein commented 2 years ago

Got it, cool that makes sense - thank you!

mchaliadzinau commented 8 months ago

IS there an option to do the same for relation?