Social networks and recommendation systems are quintessential graph database applications. This chapter explores how to model, query, and analyze social graphs, and build sophisticated recommendation engines using graph algorithms.
// Users and profiles
CREATE (alice:User:Person {
id: 'user_001',
username: 'alice',
name: 'Alice Johnson',
email: 'alice@example.com',
joinedDate: date('2020-01-15'),
bio: 'Software engineer and coffee enthusiast'
})
// Social relationships
CREATE (alice)-[:FOLLOWS {since: date('2020-02-01')}]->(bob:User)
CREATE (alice)-[:FRIENDS_WITH {since: date('2020-01-20'), confirmed: true}]->(carol:User)
// Content
CREATE (post:Post {
id: 'post_001',
content: 'Just learned about graph databases!',
timestamp: datetime('2024-01-15T10:30:00'),
likes: 0,
shares: 0
})
CREATE (alice)-[:POSTED]->(post)
// Interactions
CREATE (bob)-[:LIKED {timestamp: datetime('2024-01-15T11:00:00')}]->(post)
CREATE (carol)-[:COMMENTED {
text: 'Great topic!',
timestamp: datetime('2024-01-15T11:15:00')
}]->(post)
CREATE (group:Group {
id: 'group_001',
name: 'Graph Database Enthusiasts',
description: 'Learning and sharing about graph databases',
createdDate: date('2020-03-01'),
memberCount: 0
})
CREATE (alice)-[:MEMBER_OF {role: 'admin', joinedDate: date('2020-03-01')}]->(group)
// Privacy settings on posts
CREATE (post:Post {
content: 'Private thought',
visibility: 'friends_only',
allowComments: true
})
// Query respecting privacy
MATCH (viewer:User {id: $viewerId}), (post:Post)
WHERE post.visibility = 'public'
OR (post.visibility = 'friends_only'
AND (viewer)-[:FRIENDS_WITH]-(:User)-[:POSTED]->(post))
OR (viewer)-[:POSTED]->(post)
RETURN post
// Suggest friends: friends of friends
MATCH (user:User {id: $userId})-[:FRIENDS_WITH]->()-[:FRIENDS_WITH]->(suggestion:User)
WHERE NOT (user)-[:FRIENDS_WITH]-(suggestion)
AND user <> suggestion
WITH suggestion, count(*) AS mutualFriends
ORDER BY mutualFriends DESC
LIMIT 10
MATCH (suggestion)<-[:FRIENDS_WITH]-(mutual)-[:FRIENDS_WITH]->(user)
RETURN suggestion.name,
suggestion.bio,
mutualFriends,
collect(mutual.name) AS mutualFriendsList
// Find trending posts (last 24 hours)
MATCH (post:Post)
WHERE post.timestamp > datetime() - duration({hours: 24})
OPTIONAL MATCH (post)<-[:LIKED]-(liker)
OPTIONAL MATCH (post)<-[:SHARED]-(sharer)
WITH post, count(DISTINCT liker) AS likes, count(DISTINCT sharer) AS shares
WITH post, likes, shares, (likes * 1.0 + shares * 2.0) AS trendScore
RETURN post.content,
likes,
shares,
trendScore
ORDER BY trendScore DESC
LIMIT 20
// Personalized feed
MATCH (user:User {id: $userId})
MATCH (user)-[:FOLLOWS]->(followed:User)-[:POSTED]->(post:Post)
WHERE post.timestamp > datetime() - duration({days: 7})
OPTIONAL MATCH (post)<-[interaction:LIKED|COMMENTED]-(interactor)
WHERE (user)-[:FOLLOWS]->(interactor)
WITH post, followed, count(interaction) AS relevanceScore
RETURN post.content,
followed.name AS author,
post.timestamp,
relevanceScore
ORDER BY relevanceScore DESC, post.timestamp DESC
LIMIT 50
Recommend based on similar users' preferences:
// User-based collaborative filtering
MATCH (user:User {id: $userId})-[:PURCHASED]->(p:Product)
<-[:PURCHASED]-(similar:User)
MATCH (similar)-[:PURCHASED]->(rec:Product)
WHERE NOT (user)-[:PURCHASED]->(rec)
WITH rec, count(DISTINCT similar) AS commonUsers
RETURN rec.name,
rec.description,
commonUsers AS score
ORDER BY score DESC
LIMIT 10
Recommend similar items:
// Products similar to user's purchases
MATCH (user:User {id: $userId})-[:PURCHASED]->(p:Product)
-[:IN_CATEGORY]->(cat:Category)<-[:IN_CATEGORY]-(similar:Product)
WHERE NOT (user)-[:PURCHASED]->(similar)
AND p <> similar
WITH similar, count(DISTINCT cat) AS categoryOverlap
RETURN similar.name,
similar.price,
categoryOverlap
ORDER BY categoryOverlap DESC
LIMIT 10
// Combine multiple signals
MATCH (user:User {id: $userId})
// Collaborative signal
OPTIONAL MATCH (user)-[:PURCHASED]->()<-[:PURCHASED]-(similar:User)
-[:PURCHASED]->(collab:Product)
WHERE NOT (user)-[:PURCHASED]->(collab)
WITH user, collab, count(DISTINCT similar) AS collabScore
// Content signal
OPTIONAL MATCH (user)-[:PURCHASED]->(p:Product)
-[:IN_CATEGORY]->(cat:Category)
<-[:IN_CATEGORY]-(collab)
WITH user, collab, collabScore, count(DISTINCT cat) AS contentScore
// Social signal
OPTIONAL MATCH (user)-[:FOLLOWS]->(friend:User)-[:LIKED]->(collab)
WITH collab, collabScore, contentScore, count(DISTINCT friend) AS socialScore
// Weighted combination
WITH collab,
(collabScore * 1.0 + contentScore * 0.5 + socialScore * 0.8) AS finalScore
RETURN collab.name,
finalScore
ORDER BY finalScore DESC
LIMIT 10
// Recent interactions weighted more
MATCH (user:User {id: $userId})-[interaction:VIEWED|PURCHASED]->(item)
WITH item, interaction.timestamp AS timestamp
WITH item,
sum(exp(-duration.between(timestamp, datetime()).days / 30.0)) AS decayedScore
RETURN item.name, decayedScore
ORDER BY decayedScore DESC
// Diverse recommendations across categories
MATCH (user:User {id: $userId})-[:PURCHASED]->(p:Product)
-[:IN_CATEGORY]->(userCat:Category)
WITH user, collect(DISTINCT userCat.id) AS userCategories
MATCH (rec:Product)-[:IN_CATEGORY]->(cat:Category)
WHERE NOT rec.category IN userCategories
AND NOT (user)-[:PURCHASED]->(rec)
WITH rec, cat,
CASE WHEN cat.id IN userCategories THEN 0 ELSE 1 END AS diversityBonus
RETURN rec.name, cat.name, diversityBonus
ORDER BY diversityBonus DESC, rand()
LIMIT 10
// Recommend based on current session
MATCH (user:User {id: $userId})-[v:VIEWED]->(item:Product)
WHERE v.sessionId = $sessionId
WITH collect(item) AS sessionItems
MATCH (session_item)<-[:VIEWED]-(other:User)-[:VIEWED]->(rec:Product)
WHERE session_item IN sessionItems
AND NOT rec IN sessionItems
WITH rec, count(*) AS coOccurrence
RETURN rec.name, coOccurrence
ORDER BY coOccurrence DESC
LIMIT 5
| Metric | Formula | Interpretation |
|---|---|---|
| Precision@K | Relevant in top K / K | Accuracy of recommendations |
| Recall@K | Relevant in top K / Total Relevant | Coverage of relevant items |
| NDCG | Normalized DCG | Ranking quality |
| Diversity | Unique categories in top K | Recommendation variety |
// Update recommendations as user browses
MATCH (user:User {id: $userId})
MERGE (session:Session {id: $sessionId, userId: $userId})
ON CREATE SET session.startTime = datetime()
ON MATCH SET session.lastActivity = datetime()
WITH user, session
MATCH (product:Product {id: $productId})
MERGE (session)-[v:VIEWED]->(product)
ON CREATE SET v.timestamp = datetime(), v.count = 1
ON MATCH SET v.timestamp = datetime(), v.count = v.count + 1
// Trigger recommendation update
WITH user, session
CALL recommendations.update(user, session)
YIELD recommendations
RETURN recommendations
// Track recommendation variants
CREATE (experiment:Experiment {
id: 'exp_001',
name: 'Collaborative vs Content',
startDate: date(),
variants: ['collaborative', 'content-based']
})
// Assign user to variant
MATCH (user:User {id: $userId}), (exp:Experiment {id: 'exp_001'})
MERGE (user)-[p:PARTICIPATES_IN]->(exp)
ON CREATE SET p.variant = exp.variants[toInteger(rand() * size(exp.variants))]
RETURN p.variant
// Track outcomes
MATCH (user)-[p:PARTICIPATES_IN]->(exp),
(user)-[purchase:PURCHASED]->(product:Product)
WHERE purchase.timestamp > exp.startDate
CREATE (outcome:Outcome {
userId: user.id,
experimentId: exp.id,
variant: p.variant,
productId: product.id,
timestamp: purchase.timestamp,
revenue: purchase.amount
})
This section reconciles the recommendation ENUM tokens of the Graph Database Standard simulator with the procedures discussed in §7.1 through §7.6. The simulator exposes five recommendation tokens — COLLABORATIVE_FILTERING, CONTENT_BASED, MATRIX_FACTORIZATION, DEEP_LEARNING_RECOMMENDER, and GRAPH_NEURAL_NETWORK — reflecting the historical evolution of the field1. From the algorithm class, PAGERANK, BFS, LOUVAIN, NODE2VEC, and GRAPHSAGE are auxiliary tokens commonly applied directly on recommendation graphs2, and among the database engine ENUMs, NEO4J, NEPTUNE, and TIGERGRAPH are the most frequently deployed candidates for recommendation workloads.
| ENUM Token | Era | Representative Datasets | Representative Metric | Primary Source |
|---|---|---|---|---|
COLLABORATIVE_FILTERING | 1992– | MovieLens, Netflix Prize | RMSE 0.85–0.95 | Goldberg 19923 |
CONTENT_BASED | 2000– | News, Music | F1 0.40–0.65 | Pazzani 2007 |
MATRIX_FACTORIZATION | 2009– | Netflix Prize | RMSE 0.86 | Koren KDD 20094 |
DEEP_LEARNING_RECOMMENDER | 2017– | Amazon, Yelp | HR@10 0.60+ | He WWW 20175 |
GRAPH_NEURAL_NETWORK | 2018– | Pinterest, Reddit | NDCG@10 0.45+ | LightGCN 20206 |
The historical trajectory shown in Table 7.7.1 illustrates that recommendation systems have evolved through five paradigm shifts: collaborative filtering (1992), content-based methods (2000), matrix factorization (2009), deep learning (2017), and graph neural networks (2018)7. Importantly, no paradigm replaces its predecessors entirely; real-world industrial systems instead compose ensembles of multiple algorithms with dynamically tuned user-specific weights. Netflix, YouTube, and Amazon all operate matrix factorization and GNN models concurrently, with the relative weighting adjusted per session.
Graph neural network (GNN) based recommendation operates over the bipartite user-item graph, learning embeddings through message-passing iterations6. Landmark models include NGCF (2019), LightGCN (2020), UltraGCN (2021), HCCF (2022), and SimGCL (2022). LightGCN in particular demonstrated that removing nonlinear activation and feature transformation from the standard GCN paradigm improved recommendation accuracy, an unexpected finding that has guided subsequent simplification efforts.
The principal value propositions of GNN-based recommendation are threefold. First, high-order connectivity is explicitly leveraged, enabling meaningful recommendations even between users and items without direct interaction history. Second, the cold-start problem is mitigated by integrating social graphs and content graphs into a unified embedding space. Third, explainability is naturally enabled through path-based reasoning, which is particularly valuable in regulated domains such as healthcare and financial services8.
| Model | Year | Recall@20 | NDCG@20 | Reference |
|---|---|---|---|---|
| NGCF | 2019 | 0.1815 | 0.1623 | Wang SIGIR 20199 |
| LightGCN | 2020 | 0.1830 | 0.1637 | He SIGIR 20206 |
| UltraGCN | 2021 | 0.1864 | 0.1697 | Mao CIKM 2021 |
| HCCF | 2022 | 0.1881 | 0.1710 | Xia SIGIR 2022 |
| SimGCL | 2022 | 0.1916 | 0.1736 | Yu SIGIR 202210 |
In "LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation," He et al. demonstrate that removing feature transformation and nonlinear activation from a GCN improves rather than degrades recommendation accuracy.
Sequential recommendation models such as SASRec (Kang and McAuley, 2018), BERT4Rec (Sun et al., 2019), and GraphRec (Fan et al., 2019) combine temporal user-item interaction sequences with graph structure for richer modeling11. BERT4Rec adapts the bidirectional transformer to user behavior sequences, treating each item as a token and masking strategy as the training objective.
Global social graph assets, most notably the Facebook Open Graph and the LinkedIn Economic Graph, represent two pillars of large-scale industrial recommendation infrastructure12. Each maintains user networks on the order of three billion and 900 million respectively, with relationship types including friendship, professional connection, employment, education, and skill endorsement.
The Netflix Prize Dataset (2006–2009), although now historical, remains a touchstone benchmark for collaborative filtering research, with over 100 million ratings spanning 480,000 users and 17,770 movies. The Pinterest dataset, used in many GNN papers, contains user-image interaction data appropriate for testing visual recommendation algorithms with graph structure.
WIA-Official/wia-standards-public/tree/main/graph-database — open standard initiative providing source code for simulator, spec, API, and ebook assets cited throughout this volume; serves as the canonical verification record for all primary-source citations made by the WIA standard committee in this chapter. Canonical ENUM tokens used in this volume include NEO4J, NEPTUNE, DGRAPH, ARANGODB, JANUSGRAPH, TIGERGRAPH, MEMGRAPH, NEBULA_GRAPH, CYPHER, GREMLIN, SPARQL, GQL, PAGERANK, LOUVAIN, NODE2VEC, GRAPHSAGE, ISO_GQL_2024, W3C_RDF, W3C_SPARQL, LDBC_SNB, WIKIDATA, DBPEDIA, YAGO, CONCEPTNET.