49
votes

Any rule of thumb on where to use label vs node property vs relationship + node.

Let's have an example, say I have a store and I want to put my products in neo4j. Their identifier is the product sku, and I also want to have a categorization on them like this one is for clothes, food, electronics, and you get the idea. I'll be having a free search on my graph, like the user can search anything, and I'd return all the things related to that search string.

Would it be better to use:

  1. I have a node with sku 001, and I'll tag it a label of Food.
  2. I have a node with sku 001, and have property on this node called category:"Food"
  3. I have a node with sku 001, and I'll create another node for the Food, and will create a relationship of "category" to relate them.

I have read that if you'll be looking up a property, it's better off as a relationship + node, as traversing is much faster than looking up properties of node.

TIA

2

2 Answers

63
votes

Whether you should use a property, a label or a node for the category depends on how you will be querying the data.

(I'll assume here that you have a fairly small, fairly fixed set of categories.)

Use a property if you won't be querying by category, but just need to return the category of a node that has been found by other means. (For example: what is the category of the item with sku 001?)

Use a label if you need to query by category. (For example: what are all the foods costing less than $10?)

Use a node if you need to traverse the category without knowing what it is. (For example: what are the ten most popular items in the same category as one that the user has chosen?)

11
votes

This blog post may also be helpful because of the benchmark it contains.

I modelled the ‘relationship’ in 4 different ways…

  • Using a specific relationship type (node)-[:HAS_ADDRESS]->(address)
  • Using a generic relationship type and then filtering by end node label (node)-[:HAS]->(address:Address)
  • Using a generic relationship type and then filtering by relationship property (node)-[:HAS {type:“address”}]->(address)
  • Using a generic relationship type and then filtering by end node property (node)-[:HAS]->(address {type: “address”})

<...>

So in summary…specific relationships #ftw!