DEV Community

Michael Porter
Michael Porter

Posted on

Neo4j & GraphQL - A Match Made In Heaven

For the last 8 months, I've been working on my first paying job as a freelance software developer. It's a project that I conceived of, pitched, and sold to a business despite the fact that up to that point, I'd never built any kind of enterprise level software project. I've written a bit about my journey as a software developer and if you care to you can read some of my posts both here or on Medium that delve deeper into that part of the story. But it suffices to say, this project was a huge leap for me. So you might be wondering, how I was able to sell this idea much less accomplish it?

The answer, probably given away by the title, is that I was able to leverage the power of graphs, specifically, the Graph Database Neo4j and GraphQL everyone's favorite jumped up query language. When I discovered Neo4j I was immediately impressed by the way it was able to express highly connected data and how I could easily use the built-in data visualization tools to explore the data. I could “see,” the data in a way that I’d never been able to when using a SQL database or thinking in terms of tables and foreign keys. When you look at a graph you can literally understand how to traverse it, which makes getting from A to B and all points in between easy.

When it came time to the pitch the project I was able to give the clients a detailed view of how their data was connected and I was going to handle the complexity of their use case. Essentially, I showed them this:

Alt Text

Instead of this:

Alt Text

One is easily understandable with no training or special knowledge, the other is not. Anytime the client had a question about to handle certain situations I could pull up a simple example from the data I had and walk them through it step by step, with labeled relationships. It was a slam dunk, I convinced a room full of technology adverse people to let me digitize their data and take a chance on an untried software developer.

In the same way, pairing Neo4j with GraphQL via the GRANDstack gives me the ability to get exactly the data I want, how I want it. Do I want an assignment doc, with all it's accompanying info? No problem. Build it out in your schema like this:

type Assignment {
    id: ID
    volPage: String
    book: String
    effectiveDate: String
    dateFiled: String
    docType: String
    comments: String
    wellsDrilled: String
    grantor: Operator @relation(name:"GRANTOR" direction: "IN")
    grantee: Operator @relation(name:"GRANTEE" direction: "OUT")
    totalAcres: Float @cypher(
        statement: "MATCH (this)-[r:ASSIGNMENT_INTEREST]->(:Tract) return sum(toFloat(r.acres)) "
    )
    assignmentInterests: [AssignmnentInterest]
}

and when you query, you get an object back shaped like this:

query {
  Assignment {
    id
    volPage
    book
    effectiveDate
    dateFiled
    docType
    comments
    wellsDrilled
    grantor {
      id
      name
    }
    grantee {
      id
      name
    }
    totalAcres
  }
}

Neo4j-graphql-js allows you to make direct use of Neo4j's graph features in your api. Want to link two nodes? Simply tell your schema that a relationship exists. Want to place properties on the relationship? Make it a type:

type AssignmnentInterest @relation(name: "ASSIGNMENT_INTEREST"){
    id: ID!
    from: Assignment
    to: Tract
    acres: String
}

Want to do some math or something a little more complicated? Use Neo4j's query language Cypher to do the dirty work for you.

avgMineralPercentage: Float
    @cypher (
        statement: "MATCH (:Tract)<-[r:MINERAL_OWNERSHIP]-(this) return avg(r.mineralPercentage)"
    )

The ability to traverse the graph from one end to the other in a single network request is amazing and at times feels a little like having data super powers. I won't get too far off into the weeds of specific examples, it's enough to say that pairing Neo4j and GraphQL have given me the ability to tackle a difficult problem and make it look easy. I will write more soon about specific use cases and examples. Until then, if you're looking for a way to make your make your data wrangling easier check out these two technologies and see if you feel like I do, that they were meant to be together - a match made in heaven.

Top comments (4)

Collapse
 
godara01 profile image
Sanket Chaudhary

Hey!
can you tell how to get properties of relationships involving same type of nodes. ex.
type AssignmnentInterest @relation(name: "ASSIGNMENT_INTEREST"){
id: ID!
from: Assignment
to: Assignment
acres: String
}

Thanks

Collapse
 
muddybootscode profile image
Michael Porter

I'm not exactly sure but its possible you could do something like this:

type Assignment {
   previousAssignment: Assignment @relation(name: "ASSIGNEMNT_INTEREST", direction:(this could be out or in depeneding upon your requirements))
}

Something like that should work. If not, you could do something like create an initial installment type and have that be the first assignment in your chain. I hope this helps.

Collapse
 
logeekal profile image
Jatin Kathuria

This is a great explanation and gives me a fair introductory idea of how GraphQL is working with neo4J

Collapse
 
muddybootscode profile image
Michael Porter

Thank you, I hope its enough to get people started and understand how great they work together.