manonthemat
manonthemat

Reputation: 6251

Neo4j cypher optimization

From a set of stuff to like, I want to find out how many of a set of users like what stuff.

Indexes exist on the User label for the userId property, as well as for the StuffToLike label and its stuffId property.

Both {users} and {stuff} parameters will receive arrays with ids. For this phase, the {users} array will hold in between 100 to 1,000,000 strings, while the {stuff} array will have 100 strings in it.

This is the most simplified and fastest solution with the least db hits I have up until this point.

  MATCH (u:User) WHERE u.userId IN {users}
  MATCH (n:StuffToLike) WHERE n.stuffId IN {stuff}
  OPTIONAL MATCH (n)<-[l:LIKES]-(u)
  OPTIONAL MATCH (n)<-[d:DISLIKES]-(u)
  RETURN {
      stuffId: n.stuffId,
      name: n.name,
      likes: count(l),
      dislikes: count(d)
  } AS stuff

I don't expect real-time usability for this amount of data (yet), but it'd be great if I can run this in a reasonable amount of time.

Upvotes: 1

Views: 31

Answers (1)

Michael Hunger
Michael Hunger

Reputation: 41706

Can you try this?

MATCH (u:User) WHERE u.userId IN {users} WITH collect(u) as users
MATCH (n:StuffToLike) WHERE n.stuffId IN {stuff}
RETURN {
      stuffId: n.stuffId,
      name: n.name,
      likes: size([u in users WHERE (n)<-[:LIKES]-(u)]),
      dislikes: size([u in users WHERE (n)<-[:DISLIKES]-(u)])
  } AS stuff

Also how fast is this:

MATCH (u:User) WHERE u.userId IN {users} WITH collect(u) as users
MATCH (n:StuffToLike) WHERE n.stuffId IN {stuff}
RETURN {
      stuffId: n.stuffId,
      name: n.name,
      likes: size((n)<-[:LIKES]-()),
      dislikes: size((n)<-[:DISLIKES]-())
  } AS stuff

Upvotes: 1

Related Questions