Reputation: 313
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'});
If so, how to set model class based on the above hierarchy (Multiple labels for Node) in Spring-data-starter-neo4j
Or
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
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
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
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