0
votes

I am using Neo4j(3.2.3) and graphql. I am trying to add multiple phone numbers (dynamically) as array of strings in a single property of a user via graphql. So, a user can have as many phone numbers as s/he wants to add. For E.g.

 User{
       "name": "Neo",
       "Job": "Actor",
       "phoneNumber": [
                       "13274564",
                       "23451674",
                       "56454646"
                      ]
        }

But I am unable to get the desired result. Could someone please let me know what i am doing wrong?

Here is my graphql typeschema and mutation query of User:

    type User{

     name:String
     Job:String
     phoneNumber: [String]
    }


   type Mutation {

    addUser(
      name:String!
      Job:String
      phoneNumber: [String]       
    ): User 
   }

And here is my cypher query for resolver:

addUser(_, params) {


  let query = `MERGE(u:User {_id:apoc.create.uuid()})
              ON CREATE SET u.name= {name},
                            u.Job= {Job},
                            u.phoneNumber = ["{{phoneNumber},{phoneNumber}}"]

When I run this query via GraphiQL adding desired phone numbers, the numbers are not being updated and rather same text phoneNumber is being updated in the database like this:

error in updating the field

So, can anyone please help me out here? I have gone through apoc procedures as well but still unable to figure out how to write an appropriate cypher query for this case.

1

1 Answers

1
votes

Since you're passing an array of strings for the phoneNumber parameter you can just set the phoneNumber property on the user node to the phoneNumber parameter:

MERGE(u:User {_id:apoc.create.uuid()})
  ON CREATE SET u.name= {name},
                u.Job= {Job},
                u.phoneNumber = {phoneNumber}

If you want to handle phone number updates (keeping the previous numbers):

MERGE(u:User {_id:apoc.create.uuid()})
ON CREATE SET u.name= {name},
              u.Job= {Job}
WITH *
UNWIND {phoneNumber} AS phone
SET u.phoneNumber = coalesce(u.phoneNumber + phone, [phone]) 

A more typical approach with a graph data model would be to model each phone number as a node and connect the phone number nodes to the user node:

MERGE(u:User {_id:apoc.create.uuid()})
ON CREATE SET u.name= {name},
              u.Job= {Job}
WITH *
UNWIND {phoneNumber} AS phone
MERGE (p:PhoneNumber {number: phone}
MERGE (u)-[:HAS_PHONE_NUMBER]->(p) 

This would change your GraphQL schema slightly, to something like this:

type User {
  name: String
  job: String
  phoneNumber: [PhoneNumber]
}

type PhoneNumber {
  number: String
}

Also be sure to check out the neo4j-graphql integrations that can drive the Neo4j data model from the GraphQL schema and auto-generate resolvers.