NoSQL · Data models beyond tables
How do you model data in Neo4j?
Short answer
Model entities as labelled nodes, relationships as typed directed edges with properties, and keep traversal patterns in mind. Avoid supernodes and use indexes only for entry points.
A node has labels and properties. A relationship has a type, a direction and properties, and it is stored as a direct pointer between nodes. The model should make the important traversals explicit rather than hiding them in join tables.
CREATE (asha:User {id: "u_7", name: "Asha"})
CREATE (ravi:User {id: "u_9", name: "Ravi"})
CREATE (asha)-[:FOLLOWS {since: date("2026-01-10")}]->(ravi)
CREATE (asha)-[:PURCHASED {at: datetime()}]->(:Product {id: "sku_1"});
CREATE INDEX user_id IF NOT EXISTS FOR (u:User) ON (u.id);Modelling guidelines
- Use relationship types for the verb in the domain, such as FOLLOWS or PURCHASED
- Store properties on the relationship when they describe the connection
- Avoid a supernode that connects to millions of others; it makes traversal explode
- Index the property used to find entry nodes, then traverse from there
- Do not encode every attribute as a node; properties are cheaper for simple values
A common mistake is translating a relational schema directly into nodes and edges, including join tables. A join table often becomes a relationship with properties. Another mistake is using a graph for simple lookups that an index could serve, which adds complexity without a traversal benefit.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What is a supernode and how do you avoid one?
- 2When should a relationship have properties?
- 3How do indexes work in Neo4j?
- 4Would you model a join table as a node or a relationship?
Say it in the interview
I model entities as labelled nodes and domain verbs as typed relationships with direction and properties. The relationship itself can hold data like a timestamp, which often replaces a relational join table. I index the property used to find a starting node, then rely on traversal rather than global lookups. I avoid supernodes, because one node with millions of edges turns a cheap hop into an expensive fan-out.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live NoSQL mock interview and get scored feedback on depth, clarity and confidence.