Last active
November 7, 2019 01:54
-
-
Save voutilad/d0f42ae61ea15617491f2defe1642835 to your computer and use it in GitHub Desktop.
Measuring Journeys in Neo4j
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Run this first on an empty Neo4j database. | |
// Note: the "type" properties are only added to make JSON | |
// results read better and aren't needed. The "at" property | |
// is used to create unique Views. | |
MERGE (u1:User {name:'dave'}) | |
MERGE (u2:User {name:'not dave'}) | |
MERGE (p1:Page {page:'/page1.html'}) | |
MERGE (p2:Page {page:'/page2.html'}) | |
MERGE (p3:Page {page:'/page3.html'}) | |
MERGE (p4:Page {page:'/page4.html'}) | |
MERGE (p5:Page {page:'/page5.html'}) | |
MERGE (p6:Page {page:'/page6.html'}) | |
MERGE (p7:Page {page:'/page7.html'}) | |
MERGE (u1)-[:HAS {type:'has'}]->(v1:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p1) | |
MERGE (u1)-[:HAS {type:'has'}]->(v2:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p2) | |
MERGE (v1)-[:NEXT {type:'next'}]->(v2) | |
MERGE (u1)-[:HAS {type:'has'}]->(v3:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p3) | |
MERGE (v2)-[:NEXT {type:'next'}]->(v3) | |
MERGE (u1)-[:HAS {type:'has'}]->(v4:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p6) | |
MERGE (v3)-[:NEXT {type:'next'}]->(v4) | |
MERGE (u2)-[:HAS {type:'has'}]->(v5:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p1) | |
MERGE (u2)-[:HAS {type:'has'}]->(v6:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p4) | |
MERGE (v5)-[:NEXT {type:'next'}]->(v6) | |
MERGE (u2)-[:HAS {type:'has'}]->(v7:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p3) | |
MERGE (v6)-[:NEXT {type:'next'}]->(v7) | |
MERGE (u2)-[:HAS {type:'has'}]->(v8:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p6) | |
MERGE (v7)-[:NEXT {type:'next'}]->(v8) | |
// duplicate some page views by nav'ing to them again | |
MERGE (u2)-[:HAS {type:'has'}]->(v9:View {type:'view', at:rand()})-[:OF {type:'of'}]->(p3) | |
MERGE (v8)-[:NEXT {type:'next'}]->(v9) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Find the "journeys" in terms of Views. To increase journey length, add | |
// additional requirements to the [:NEXT] relationship like [:NEXT*n] for a | |
// length of n+1 | |
MATCH path=(begin:View)-[:NEXT]->(finish:View) | |
// Lookup all Pages in the Journey associated with the Views, using the | |
// "path" from the previous MATCH | |
WITH path | |
UNWIND nodes(path) AS view | |
MATCH (view)-[:OF]->(p:Page) | |
// Aggregate the list of Pages along the identified "path" | |
// If using a path of length n > 2, add additional MATCH | |
// statements and WHERE clauses | |
WITH path, collect(p.page) as pageView | |
MATCH (p1:Page), (p2:Page) | |
WHERE p1.page = pageView[0] | |
AND p2.page = pageView[1] | |
// Count occurrences of ordered path arrays. Adjust if | |
// using a path of length n > 2 by updating array literals | |
// to be [p1, p2, ..., pn] | |
WITH [p1, p2] AS pathList, count([p1, p2]) AS cnt | |
// Upsert a Journey node with the latest computed count, constructing | |
// a Journey "id" based on the constituent order parts of a path. This could | |
// be rewritten to programmatically join all elements of PATH with the delimiter | |
MERGE (j:Journey {id: pathList[0].page + '-' + pathList[1].page, count: cnt}) | |
// Upsert the relationship between the Journey and the Pages | |
WITH j, pathList[0] as p1, pathList[1] as p2 | |
MERGE (j)-[:CONTAINS]->(p1) | |
MERGE (j)-[:CONTAINS]->(p2) | |
// Return journey, pages, and the journey's count making sure to | |
// include both the Page nodes (p1, p2), Journey (j), and the aggregations | |
RETURN j as Journey, p1 as Page1, p2 as Page2, j.count as Count |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment