neo4jgraphqlneo4j-graphql-js

neo4j-graphql-js custom return type for @cypher query


I'm trying to extend the graphql schema autogenerated with neo4j-graphql-js

this is my graphql schema

typeDefs

type Person {
   _id: Long!
   addresslocation: Point!
   confirmedtime: DateTime!
   healthstatus: String!
   id: String!
   name: String!
   performs_visit: [Visit] @relation(name: "PERFORMS_VISIT", direction: OUT)
   visits: [Place] @relation(name: "VISITS", direction: OUT)
   VISITS_rel: [VISITS]
}

type Place {
   _id: Long!
   homelocation: Point!
   id: String!
   name: String!
   type: String!
   part_of: [Region] @relation(name: "PART_OF", direction: OUT)
   visits: [Visit] @relation(name: "LOCATED_AT", direction: IN)
   persons: [Person] @relation(name: "VISITS", direction: IN)
}

type Visit {
   _id: Long!
   duration: String!
   endtime: DateTime!
   id: String!
   starttime: DateTime!
   located_at: [Place] @relation(name: "LOCATED_AT", direction: OUT)
   persons: [Person] @relation(name: "PERFORMS_VISIT", direction: IN)
}

type Region {
   _id: Long!
   name: String!
   places: [Place] @relation(name: "PART_OF", direction: IN)
}

type Country {
   _id: Long!
   name: String!
}

type Continent {
   _id: Long!
   name: String!
}



type VISITS @relation(name: "VISITS") {
  from: Person!
  to: Place!
  duration: String!
  endtime: DateTime!
  id: String!
  starttime: DateTime!
}

Now i extends Person to perform a custom query, in order to do that i'm using the @cypher directive

typeDefs2

type Person {
        potentialSick: [Person] @cypher(statement: """
            MATCH (p:this)--(v1:Visit)--(pl:Place)--(v2:Visit)--(p2:Person {healthstatus:"Healthy"})
            return *
        """)
  }

I create the schema by merging the two typeDefs and it works as expected

export const schema = makeAugmentedSchema({
    typeDefs: mergeTypeDefs([typeDefs, typeDefs2]),
    config: {
        debug: true,
    },
});

QUESTION

It is possible to return a custom type (mapped in graphql) from my custom query potentialSick ?

My goal is to return a type similar to this

type PotentialSick {
    id: ID
    name: String
    overlapPlaces: [Place] 
}

where overlap places is the pl in my neo4j query

MATCH (p:this)--(v1:Visit)--(pl:Place)--(v2:Visit)--(p2:Person {healthstatus:"Healthy"})

Solution

  • I realize that neo4j-graphql-js is a query builder, so i can obtain my data by using graphql just using the main schema. And my query will be:

    {
      Person(filter: { healthstatus: "Sick" }) {
        id
        visits {
          _id
          persons(filter: { healthstatus: "Healthy" }) {
            _id
          }
        }
      }
    }
    

    with this principle in mind for more complex queries that needs @cyper i can extend the base schema of each type and rely on graphql features

    as an example

    type Person {
            potentialSick: [Place] @cypher(statement: """
                MATCH path =(this)-[:VISITS]->(place:Place)<-[:VISITS]-(p2:Person {healthstatus:"Healthy"})
                return place
            """)
    

    potentialSick return places and then to obtain the person that visit that place i can just use graphql

    {
      Person(filter: { healthstatus: "Sick" }) {
        id
        potentialSick {
          persons (filter: { healthstatus: "Healthy" }){
            _id
          }
        }
      }
    }