JohnnyM
JohnnyM

Reputation: 1273

Neo4j - adding extra relationships between nodes in a list

I have a list of nodes representing a history of events for users forming, a following pattern:

()-[:s]->()-[:s]->() and so on

Each of the nodes of the list belongs to a user (is connected via a relationship).

I'm trying to create individual user histories (add a :succeeds_for_user relationship between all events that happend for a particular user, such that each event has only one consecutive event).

I was trying to do something like this to extract nodes that should be in a relationship:

start u = node:class(_class = "User")
match p = shortestPath(n-[:s*..]->m), n-[:belongs_to]-u-[:belongs_to]-m
where n <> m
with n, MIN(length(p)) as l
match p = n-[:s*1..]->m
where length(p) = l  
return n._id, m._id, extract(x IN nodes(p): x._id)

but it is painfully slow.

Does anyone know a better way to do it?

Upvotes: 0

Views: 87

Answers (1)

Thomas Fenzl
Thomas Fenzl

Reputation: 4392

Neo4j is calculating a lot of shortest paths there.

Assuming that you have a history start node (with for the purpose of my query has id x), you can get an ordered list of event nodes with corresponding user id like this:

"START n=node(x) # history start
 MATCH p = n-[:FOLLOWS*1..]->(m)<-[:DID]-u  # match from start up to user nodes
 return u._id,
     reduce(id=0, 
            n in filter(n in nodes(p): n._class != 'User'): n._id) 
     # get the id of the last node in the path that is not a User 
     order by length(p) # ordered by path length, thus place in history"

You can then iterate the result in your program and add relationships between nodes belonging to the same user. I don't have a fitting big dataset, but it might be faster.

Upvotes: 1

Related Questions