Ejemplos Neo4j

Ejemplos de base de datos de grafos Neo4j incluyendo consultas Cypher, modelado de datos y algoritmos de grafos

💻 Operaciones Básicas Neo4j cypher

🟢 simple ⭐⭐

Operaciones CRUD fundamentales con Neo4j y lenguaje de consulta Cypher

⏱️ 15 min 🏷️ neo4j, cypher, graph, database, nosql
Prerequisites: Basic database concepts, Understanding of graph theory
-- Neo4j Basic Operations
-- Cypher Query Language Examples

-- 1. Create nodes
-- Create a single person node
CREATE (p:Person {name: 'Alice', age: 30, email: '[email protected]'})

-- Create multiple nodes
CREATE
  (bob:Person {name: 'Bob', age: 25, email: '[email protected]'}),
  (charlie:Person {name: 'Charlie', age: 35, email: '[email protected]'}),
  (company:Company {name: 'TechCorp', founded: 2010, industry: 'Technology'})

-- 2. Create relationships
-- Alice works at TechCorp
MATCH (alice:Person {name: 'Alice'}), (company:Company {name: 'TechCorp'})
CREATE (alice)-[:WORKS_AT {position: 'Developer', startDate: '2020-01-15'}]->(company)

-- Bob works at TechCorp as Manager
MATCH (bob:Person {name: 'Bob'}), (company:Company {name: 'TechCorp'})
CREATE (bob)-[:WORKS_AT {position: 'Manager', startDate: '2019-03-10'}]->(company)

-- Alice knows Bob (friendship)
MATCH (alice:Person {name: 'Alice'}), (bob:Person {name: 'Bob'})
CREATE (alice)-[:KNOWS {since: '2019', relationship: 'friend'}]->(bob)
CREATE (bob)-[:KNOWS {since: '2019', relationship: 'friend'}]->(alice)

-- Bob manages Charlie
MATCH (bob:Person {name: 'Bob'}), (charlie:Person {name: 'Charlie'})
CREATE (bob)-[:MANAGES {since: '2021-06-01'}]->(charlie)

-- 3. Read/Query nodes
-- Find all people
MATCH (p:Person)
RETURN p.name, p.age, p.email
ORDER BY p.age DESC

-- Find people older than 28
MATCH (p:Person)
WHERE p.age > 28
RETURN p.name, p.age

-- Find all companies
MATCH (c:Company)
RETURN c.name, c.industry, c.founded

-- 4. Query with relationships
-- Find all people who work at TechCorp
MATCH (p:Person)-[:WORKS_AT]->(c:Company {name: 'TechCorp'})
RETURN p.name, p.age

-- Find who works where and in what position
MATCH (p:Person)-[r:WORKS_AT]->(c:Company)
RETURN p.name AS employee, c.name AS company, r.position AS position

-- Find Alice's colleagues
MATCH (alice:Person {name: 'Alice'})-[:WORKS_AT]->(c:Company)<-[:WORKS_AT]-(colleague:Person)
WHERE alice <> colleague
RETURN colleague.name AS colleague_name

-- 5. Update operations
-- Update Alice's age
MATCH (p:Person {name: 'Alice'})
SET p.age = 31, p.lastUpdated = timestamp()
RETURN p

-- Add a new property to all people
MATCH (p:Person)
SET p.status = 'active', p.createdAt = timestamp()
RETURN p.name, p.status

-- 6. Delete operations
-- Delete a specific relationship
MATCH (alice:Person {name: 'Alice'})-[r:KNOWS]->(bob:Person {name: 'Bob'})
DELETE r

-- Delete a node and all its relationships
MATCH (p:Person {name: 'Charlie'})
DETACH DELETE p

-- 7. Advanced queries
-- Count nodes by label
MATCH (n)
RETURN labels(n) AS label, count(n) AS count

-- Find people with specific number of connections
MATCH (p:Person)-[:KNOWS]-(friend)
WITH p, count(friend) AS friendCount
WHERE friendCount > 2
RETURN p.name, friendCount

-- Shortest path between two people
MATCH (alice:Person {name: 'Alice'}), (bob:Person {name: 'Bob'}),
      path = shortestPath((alice)-[*]-(bob))
RETURN path

-- 8. Aggregation functions
-- Average age of people
MATCH (p:Person)
RETURN avg(p.age) AS averageAge, min(p.age) AS minAge, max(p.age) AS maxAge

-- Count employees per company
MATCH (c:Company)<-[r:WORKS_AT]-(p:Person)
RETURN c.name AS company, count(p) AS employeeCount
ORDER BY employeeCount DESC

-- 9. Conditional queries
-- People with different age categories
MATCH (p:Person)
RETURN
  p.name,
  p.age,
  CASE
    WHEN p.age < 25 THEN 'Young'
    WHEN p.age < 35 THEN 'Adult'
    ELSE 'Senior'
  END AS ageCategory

-- 10. Pattern matching
-- Find friends of friends (2-hop connections)
MATCH (person:Person {name: 'Alice'})-[:KNOWS*2]-(fof:Person)
WHERE NOT (person)-[:KNOWS]-(fof)
RETURN DISTINCT fof.name AS friendOfFriend

-- Find people who work in Technology industry
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
WHERE c.industry = 'Technology'
RETURN p.name, c.name

💻 Algoritmos de Grafos Neo4j cypher

🟡 intermediate ⭐⭐⭐⭐

Algoritmos de grafos comunes implementados usando Neo4j Cypher

⏱️ 30 min 🏷️ neo4j, algorithms, graph theory, analytics
Prerequisites: Basic Neo4j operations, Graph theory fundamentals
-- Neo4j Graph Algorithms
-- Common graph algorithms and patterns

-- Setup: Create a social network graph
CREATE
  (alice:Person {name: 'Alice', age: 30}),
  (bob:Person {name: 'Bob', age: 25}),
  (charlie:Person {name: 'Charlie', age: 35}),
  (diana:Person {name: 'Diana', age: 28}),
  (eve:Person {name: 'Eve', age: 32}),
  (frank:Person {name: 'Frank', age: 29}),
  (alice)-[:FRIENDS {weight: 0.8}]->(bob),
  (alice)-[:FRIENDS {weight: 0.9}]->(charlie),
  (bob)-[:FRIENDS {weight: 0.7}]->(charlie),
  (charlie)-[:FRIENDS {weight: 0.6}]->(diana),
  (diana)-[:FRIENDS {weight: 0.8}]->(eve),
  (eve)-[:FRIENDS {weight: 0.9}]->(frank),
  (frank)-[:FRIENDS {weight: 0.7}]->(alice),
  (alice)-[:FRIENDS {weight: 0.5}]->(eve),
  (bob)-[:FRIENDS {weight: 0.6}]->(diana)

-- 1. Degree Centrality
-- Find most connected people (highest degree)
MATCH (p:Person)
WITH p, size((p)-[:FRIENDS]-()) AS degree
RETURN p.name, degree
ORDER BY degree DESC

-- 2. Betweenness Centrality
-- Find people who bridge different communities
MATCH (p:Person)
WITH p,
     collect(DISTINCT id(p)) AS allNodes
UNWIND allNodes AS startNode
UNWIND allNodes AS endNode
MATCH path = allShortestPaths((startNode)-[:FRIENDS*]-(endNode))
WITH p, count(DISTINCT path) AS pathsCount
WHERE any(node IN nodes(path) WHERE id(node) = id(p)) AND startNode <> endNode
RETURN p.name, pathsCount
ORDER BY pathsCount DESC

-- 3. Community Detection using Label Propagation
-- Using Neo4j Graph Data Science Library (if installed)
-- CALL gds.labelPropagation.stream('myGraph')
-- YIELD nodeId, label
-- RETURN gds.util.asNode(nodeId).name AS name, label
-- ORDER BY label, name

-- Manual community detection using modularity
MATCH (p:Person)
WITH p, size((p)-[:FRIENDS]-()) AS degree
ORDER BY degree DESC
WITH collect(p) AS nodes
UNWIND range(0, size(nodes)-1) AS i
WITH nodes[i] AS node, i
MATCH (node)-[:FRIENDS]-(neighbor)
WITH node, collect(neighbor) AS neighbors
RETURN node.name, size(neighbors) AS neighborCount

-- 4. Path Finding Algorithms
-- Find all paths up to 3 hops
MATCH (start:Person {name: 'Alice'}), (end:Person {name: 'Eve'}),
      path = (start)-[:FRIENDS*1..3]-(end)
RETURN path, length(path) AS pathLength
ORDER BY pathLength

-- Find weighted shortest path
MATCH (start:Person {name: 'Alice'}), (end:Person {name: 'Eve'}),
      path = (start)-[:FRIENDS*]-(end)
WITH path, reduce(total = 0, rel IN relationships(path) | total + rel.weight) AS totalWeight
RETURN path, totalWeight
ORDER BY totalWeight ASC
LIMIT 1

-- 5. Triangle Detection
-- Find all triangles in the network
MATCH (a:Person)-[:FRIENDS]-(b:Person)-[:FRIENDS]-(c:Person)-[:FRIENDS]-(a)
WHERE id(a) < id(b) AND id(b) < id(c)
RETURN a.name AS person1, b.name AS person2, c.name AS person3

-- Count triangles per person
MATCH (a:Person)-[:FRIENDS]-(b:Person)-[:FRIENDS]-(c:Person)-[:FRIENDS]-(a)
WITH a, count(DISTINCT b) AS triangleCount
RETURN a.name, triangleCount
ORDER BY triangleCount DESC

-- 6. PageRank Algorithm
-- Simple PageRank implementation
MATCH (p:Person)
WITH collect(p) AS allNodes
UNWIND allNodes AS node
MATCH (node)<-[:FRIENDS]-(neighbor)
WITH node, count(neighbor) AS inDegree
RETURN node.name, inDegree
ORDER BY inDegree DESC

-- 7. Closeness Centrality
-- Find people with shortest average path to others
MATCH (p:Person)
WITH p
MATCH path = shortestPath((p)-[:FRIENDS*]-(other:Person))
WHERE p <> other
WITH p, avg(length(path)) AS avgDistance
RETURN p.name, avgDistance
ORDER BY avgDistance ASC

-- 8. Graph Traversal
-- Breadth-First Search (BFS) pattern
MATCH (start:Person {name: 'Alice'})
CALL {
  WITH start
  MATCH (start)-[:FRIENDS*1..3]-(reach:Person)
  WHERE NOT (start)-[:FRIENDS]-(reach)
  RETURN DISTINCT reach, length(shortestPath((start)-[:FRIENDS*]-(reach))) AS distance
}
RETURN reach.name, distance
ORDER BY distance

-- 9. Recommendation Engine
-- Recommend friends based on mutual connections
MATCH (p:Person {name: 'Alice'})-[:FRIENDS]-(friend)-[:FRIENDS]-(recommended:Person)
WHERE NOT (p)-[:FRIENDS]-(recommended) AND p <> recommended
WITH recommended, count(DISTINCT friend) AS mutualFriends
RETURN recommended.name, mutualFriends
ORDER BY mutualFriends DESC

-- 10. Influence Propagation
-- Simulate information spread through the network
MATCH (start:Person {name: 'Alice'})
WITH start
MATCH path = (start)-[:FRIENDS*0..3]-(reached:Person)
WITH DISTINCT reached, length(path) AS hopCount
RETURN reached.name, hopCount
ORDER BY hopCount, reached.name

-- 11. Graph Density Calculation
-- Calculate overall network density
MATCH (p:Person)
WITH count(p) AS totalNodes
MATCH ()-[:FRIENDS]-()
WITH totalNodes, count(DISTINCT [startNode, endNode]) AS totalEdges
RETURN totalNodes, totalEdges, (2 * totalEdges) / (totalNodes * (totalNodes - 1)) AS density

-- 12. Connected Components
-- Find connected components in the graph
MATCH (p:Person)
WITH p
MATCH path = (p)-[:FRIENDS*]-(connected:Person)
WITH p, collect(DISTINCT connected) AS component
RETURN p.name, component
ORDER BY size(component) DESC

💻 Modelado de Datos Neo4j cypher

🟡 intermediate ⭐⭐⭐

Mejores prácticas para modelar datos en la base de datos de grafos Neo4j

⏱️ 25 min 🏷️ neo4j, data modeling, design patterns, schema
Prerequisites: Basic Neo4j operations, Data modeling concepts
-- Neo4j Data Modeling Best Practices
-- Examples of different data modeling patterns

-- 1. Social Network Model
-- People, Posts, Comments, Likes

-- Create entities
CREATE
  (alice:User {
    userId: 'user1',
    name: 'Alice Johnson',
    email: '[email protected]',
    joinDate: date('2020-01-15'),
    isActive: true
  }),
  (bob:User {
    userId: 'user2',
    name: 'Bob Smith',
    email: '[email protected]',
    joinDate: date('2020-03-20'),
    isActive: true
  }),
  (post1:Post {
    postId: 'post1',
    title: 'My First Post',
    content: 'Hello everyone!',
    createdAt: datetime('2020-06-01T10:00:00'),
    likes: 5
  }),
  (post2:Post {
    postId: 'post2',
    title: 'Graph Databases are Cool',
    content: 'Learning about Neo4j...',
    createdAt: datetime('2020-06-02T14:30:00'),
    likes: 12
  }),
  (comment1:Comment {
    commentId: 'comment1',
    content: 'Great post!',
    createdAt: datetime('2020-06-01T11:00:00')
  })

-- Create relationships
CREATE
  (alice)-[:AUTHORED]->(post1),
  (alice)-[:AUTHORED]->(post2),
  (bob)-[:COMMENTED_ON]->(post1),
  (bob)-[:COMMENTED {at: datetime('2020-06-01T11:00:00')}]->(comment1),
  (comment1)-[:ON_POST]->(post1),
  (alice)-[:LIKED {at: datetime('2020-06-01T12:00:00')}]->(post1),
  (bob)-[:FOLLOWS {since: date('2020-04-01')}]->(alice)

-- 2. E-commerce Model
-- Products, Categories, Orders, Customers, Reviews

-- Create product catalog
CREATE
  (laptop:Product {
    productId: 'prod1',
    name: 'Laptop Pro',
    price: 999.99,
    inStock: 50,
    brand: 'TechBrand'
  }),
  (mouse:Product {
    productId: 'prod2',
    name: 'Wireless Mouse',
    price: 29.99,
    inStock: 200,
    brand: 'TechBrand'
  }),
  (electronics:Category {
    categoryId: 'cat1',
    name: 'Electronics',
    description: 'Electronic devices and accessories'
  }),
  (computers:Category {
    categoryId: 'cat2',
    name: 'Computers',
    description: 'Laptops and desktop computers'
  }),
  (accessories:Category {
    categoryId: 'cat3',
    name: 'Accessories',
    description: 'Computer accessories'
  })

-- Create category hierarchy and product categorization
CREATE
  (laptop)-[:IN_CATEGORY]->(computers),
  (mouse)-[:IN_CATEGORY]->(accessories),
  (computers)-[:SUBCATEGORY_OF]->(electronics),
  (accessories)-[:SUBCATEGORY_OF]->(electronics)

-- Create customers and orders
CREATE
  (customer1:Customer {
    customerId: 'cust1',
    name: 'John Doe',
    email: '[email protected]',
    joinDate: date('2019-11-01')
  }),
  (order1:Order {
    orderId: 'order1',
    orderDate: datetime('2020-05-15T10:30:00'),
    totalAmount: 1029.98,
    status: 'delivered'
  })

-- Create relationships
CREATE
  (customer1)-[:PLACED]->(order1),
  (order1)-[:CONTAINS {quantity: 1, price: 999.99}]->(laptop),
  (order1)-[:CONTAINS {quantity: 1, price: 29.99}]->(mouse)

-- 3. Movie Database Model
-- Movies, Actors, Directors, Genres

CREATE
  (movie1:Movie {
    title: 'The Matrix',
    releaseYear: 1999,
    duration: 136,
    rating: 'R'
  }),
  (movie2:Movie {
    title: 'Inception',
    releaseYear: 2010,
    duration: 148,
    rating: 'PG-13'
  }),
  (actor1:Person {
    name: 'Keanu Reeves',
    birthYear: 1964
  }),
  (actor2:Person {
    name: 'Leonardo DiCaprio',
    birthYear: 1974
  }),
  (director1:Person {
    name: 'Lana Wachowski',
    birthYear: 1965
  }),
  (director2:Person {
    name: 'Christopher Nolan',
    birthYear: 1970
  }),
  (scifi:Genre {name: 'Science Fiction'}),
  (action:Genre {name: 'Action'}),
  (thriller:Genre {name: 'Thriller'})

-- Create relationships
CREATE
  (actor1)-[:ACTED_IN {role: 'Neo', billingOrder: 1}]->(movie1),
  (actor2)-[:ACTED_IN {role: 'Cobb', billingOrder: 1}]->(movie2),
  (director1)-[:DIRECTED]->(movie1),
  (director2)-[:DIRECTED]->(movie2),
  (movie1)-[:HAS_GENRE]->(scifi),
  (movie1)-[:HAS_GENRE]->(action),
  (movie2)-[:HAS_GENRE]->(scifi),
  (movie2)-[:HAS_GENRE]->(thriller)

-- 4. Knowledge Graph Model
-- Concepts, Entities, Relationships, Facts

CREATE
  (concept1:Concept {
    name: 'Machine Learning',
    definition: 'Algorithms that improve through experience',
    domain: 'Computer Science'
  }),
  (concept2:Concept {
    name: 'Neural Network',
    definition: 'Computing systems inspired by biological neural networks',
    domain: 'Computer Science'
  }),
  (concept3:Concept {
    name: 'Deep Learning',
    definition: 'Machine learning using artificial neural networks',
    domain: 'Computer Science'
  }),
  (researcher:Person {
    name: 'Dr. Jane Smith',
    field: 'Artificial Intelligence'
  })

-- Create knowledge relationships
CREATE
  (concept2)-[:IS_A]->(concept1),
  (concept3)-[:USES_TECHNIQUE]->(concept2),
  (concept3)-[:SUBFIELD_OF]->(concept1),
  (researcher)-[:EXPERT_IN]->(concept3)

-- 5. Query Patterns for Different Models

-- Social Network Queries
-- Find users who liked posts about specific topics
MATCH (user:User)-[:LIKED]->(post:Post)
WHERE post.title CONTAINS 'Graph'
RETURN user.name, post.title

-- Find friend recommendations
MATCH (user:User {userId: 'user1'})-[:FOLLOWS*1..2]-(potential:User)
WHERE NOT (user)-[:FOLLOWS]->(potential) AND user <> potential
RETURN DISTINCT potential.name

-- E-commerce Queries
-- Find customers who bought products in the same category
MATCH (c1:Customer)-[:PLACED]->(:Order)-[:CONTAINS]->(p1:Product)-[:IN_CATEGORY]->(cat:Category),
      (c2:Customer)-[:PLACED]->(:Order)-[:CONTAINS]->(p2:Product)-[:IN_CATEGORY]->(cat)
WHERE c1 <> c2 AND c1.customerId = 'cust1'
RETURN DISTINCT c2.name, cat.name, collect(p2.name) as productsBought

-- Find frequently bought together products
MATCH (order:Order)-[:CONTAINS]->(p1:Product),
      (order)-[:CONTAINS]->(p2:Product)
WHERE id(p1) < id(p2)
WITH p1, p2, count(order) as orderCount
RETURN p1.name, p2.name, orderCount
ORDER BY orderCount DESC

-- Movie Database Queries
-- Find actors who have worked with the same director
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)
WITH director, collect(actor.name) as actors
WHERE size(actors) > 1
RETURN director.name, actors

-- Find movies with common genres
MATCH (m1:Movie)-[:HAS_GENRE]->(genre:Genre)<-[:HAS_GENRE]-(m2:Movie)
WHERE id(m1) < id(m2)
WITH m1, m2, collect(genre.name) as commonGenres
WHERE size(commonGenres) > 0
RETURN m1.title, m2.title, commonGenres