I don't see what you are trying to achieve with the nested FOREACH
loops.
If you really get both the hit
node and session
node, a simple MERGE
should be fine. I think you have to include hit
in the WITH
statement though.
MERGE (session :Session { id: "xxx" })
MERGE (hit:Hit { date_time:"2015-04-03T06:00:44" })
CREATE (hit)-[:IN_SESSION]->(session)
WITH session, hit
MATCH (prev_hit:Hit)-[:IN_SESSION]->(session)
WHERE prev_hit <> hit // make sure that you only match other hits
WITH hit, prev_hit
ORDER BY prev_hit.date_time DESC LIMIT 1
MERGE (prev_hit)-[:NEXT]->(hit) // create relationship between the two
Update
I updated the query to only match prev_hit
which are not the current hit. The query above works as you want, that is it creates a single NEXT
relationship to a single Hit
node related to the same Session
. See here: http://console.neo4j.org/?id=ov7mer
There might be issues with the date_time. You store it as a String I think, sorting might not always give you the expected result.
Update 2
Regarding your second comment: If you go over your file line by line and add Hit
nodes, you can only add relationships to Hit
nodes which have been added already. If you want a continuous chain of NEXT
relationships between Hit
nodes you can only do this in one query if you make sure that the entries of your CSV file are ordered ascending by date_time.
You can add the NEXT
relationships between the Hit
nodes later as described here: http://www.markhneedham.com/blog/2014/04/19/neo4j-cypher-creating-relationships-between-a-collection-of-nodes-invalid-input/
Start your query with:
MATCH (s:Session)--(hit:Hit)
// first order by hit.date_time
WITH DISTINCT s, hit ORDER BY hit.date_time DESC
// this will return one row per session with the hits in a collection
WITH s, collect(hit) AS this_session_hits
// try this to check the ordering:
// RETURN s.session_id, this_session_hits
// the following queries will be done on each row, this is like iterating over the sessions
FOREACH(i in RANGE(0, length(this_session_hits)-2) |
FOREACH(e1 in [this_session_hits[i]] |
FOREACH(e2 in [this_session_hits[i+1]] |
MERGE (e1)-[:NEXT]->(e2))))
Final Answer ;)
This query works on the dataset in your neo4j console (http://console.neo4j.org/?id=mginka). It connects all Hit
from a session with NEXT
relationships.
MATCH (s:Session)<--(hit:Hit)
WITH DISTINCT s, hit
ORDER BY hit.date_time ASC
WITH s, collect(hit) AS this_session_hits
FOREACH (i IN RANGE(0, length(this_session_hits)-2)|
FOREACH (e1 IN [this_session_hits[i]]|
FOREACH (e2 IN [this_session_hits[i+1]]|
MERGE (e1)-[:NEXT]->(e2))))