Raj Malhotra
Raj Malhotra

Reputation: 89

Modelling data in neo4j

I have a list of users for my database, and a fixed set of 30-35 properties which each user may have. These properties may change over time, so I have created nodes for each of these properties and one node for each user .

For updating the properties, I connect or delete the relationship for that user with the corresponding properties, I have assigned each user and property a unique id.

I would like to answer queries like count of user which have ( property1 and property2 and property3 ), count of users with (property1 or property2 ), etc

How can I answer query of first type ? for two properties I use :

match (p1:property)<--(n:user)-->(p2:property) p1.id=1 and p2.id=2  return count(distinct(n))

How can I answer for multiple properties joined with 'and' clause, It's easy for 'or' clause using :

 match (n:user)-->(p:property) where p.id in [1,2] return count(distinct(n)) 

How can I answer queries with combination of 'and' and 'or' clauses like: users with ( (property1 and property2) or (property1 and property2) )

Also can indices help in the above case as I am mostly interested in getting count of users ?

Upvotes: 1

Views: 39

Answers (2)

Tom Geudens
Tom Geudens

Reputation: 2656

I'm still not convinced that you want every property to be a node. New properties can be SET, obsolete ones can be REMOVEd. And the existence of a property can be checked with EXISTS.

There surely can be a reason to turn a property into a node, but the above is not it (imo).

Hope this helps, Tom

Upvotes: 0

Bruno Peres
Bruno Peres

Reputation: 16355

In all cases you can check by the path existence between a node and properties, like this:

1 - Count of user which have property1 and property2 and property3:

MATCH (u:user)
WHERE
    (u)-->(:property {id : 1})
AND
    (u)-->(:property {id : 2})
AND
    (u)-->(:property {id : 3})
RETURN COUNT(DISTINCT(u))

Alternatively:

MATCH (u:user),
(u)-->(:property {id : 1}),
(u)-->(:property {id : 2}),
(u)-->(:property {id : 3})
RETURN COUNT(DISTINCT(u))

2 - Count of user which have property1 and property2 OR property3:

MATCH (u:user)
WHERE
    (u)-->(:property {id : 1})
AND
    (u)-->(:property {id : 2})
OR
    (u)-->(:property {id : 3})
RETURN COUNT(DISTINCT(u))

To improve performance try adding an index in the id property of your :property nodes. This way:

CREATE INDEX ON :property(id)

Upvotes: 1

Related Questions