CdVr
CdVr

Reputation: 313

neo4j data modelling multiple labels for a node with hierarchy

Assume i'm creating products of Mobiles and Tablets labeling as

create (n:Mobiles:Electronics:Communication Devices {name:'XXXX'}); create (n:Tablets:Electronics:Communication Devices {name:'YYYY'});

and after with Laptops. So, the following

create (n:Laptops:Electronics {name:'AAAA'});

CREATE (:CommunicationDevices)-[:SubType]->(:Electronics)-[:SubType]->(:Mobiles)

Which one is the preferred way to model Product Catalogue? Please show some insights on graph modelling for this use case.

Upvotes: 0

Views: 784

Answers (3)

Tomo Česnik
Tomo Česnik

Reputation: 146

There is this article (https://medium.com/neo4j/graph-modeling-labels-71775ff7d121) created by one of the main people at Neo4j that suggests not to model class hierarchies with labels.

Upvotes: 0

Steffen Harbich
Steffen Harbich

Reputation: 2759

Here is another opinion based on the approaches described by meistermeier.

How do you model your graph depends on your data and what is queried later. If you will create Java classes for all of your hierarchical product categories you can go with the inheritance approach (first approach from meistermeier). This is especially useful when you have dedicated properties in product categories, e.g. "screenSize" in Electronics or "MAC" in CommunicationDevice or "gpsSensor" in MobilePhone. Queries by label are efficient, i.e. it would be fast to query for these product categories. Additionally, you could model common properties like "productNumber" in a root class Product or something.

I think the second approach from meistermeier doesn't fit your needs of a product catalogue. At most, if you do like

@NodeEntity
public class Laptop {

    @Relationship("BASE")
    Electronic electronic;
}

which is the other way around and you would have to create a Laptop, an Electronic and a CommunicationDevice node for each laptop. But in that case the first approach is more elegant because you would have only one Laptop node with all properties from Laptop, Electronic and CommunicationDevice.

Therefor I recommend the first approach.

Upvotes: 0

meistermeier
meistermeier

Reputation: 8262

It is possible to have multiple labels on a node created (or loaded) by Spring Data Neo4j/Neo4j-OGM.

Let my draw the interfaces/classes first.

@NodeEntity
public interface CommunicationDevice {}

@NodeEntity
public class Electronics {}

@NodeEntity
public class Mobiles extends Electronics implements CommunicationDevice {}

@NodeEntity
public class Tablets extends Electronics implements CommunicationDevice {}

@NodeEntity // here we do not want the label CommunicationDevice
public class Laptops extends Electronics {}

You can see that the Java class model reflects directly the hierarchy you want to express through the labels.

The second approach could be achieved through @Relationship mappings like

@NodeEntity
public class CommunicationDevice {

    @Relationship("SubType")
    Set<Electronics> electronics;
}

So there won't be any inheritance but every class represents one node "type".

My suggestion is that it really depends on the data you want to store. In your examples there are only leaf-nodes and no data for e.g. CommunicationDevice. While the first option stores the products directly with their labels, the second option reflects more the hierarchy for navigation to the products.

Personally I think that the best approach is to really store the path / navigation to the product (second option) instead of using just the labels. Otherwise you won't have a real hierarchy in your graph with just the labels but only in the application.

Upvotes: 2

Related Questions