1. Hiểu rõ mô hình Graph và cấu trúc dữ liệu
Khác với cơ sở dữ liệu quan hệ (RDBMS) dùng bảng (table) và dòng (row), Neo4j lưu trữ dữ liệu dưới dạng các nút (Node) và quan hệ (Relationship). Việc nắm vững 3 khái niệm này là nền tảng để viết query hiệu quả.
1.1 Node (Nút) và Label (Nhãn)
Node là đơn vị dữ liệu cơ bản, đại diện cho một thực thể như Người, Sản phẩm, hoặc Thành phố. Mỗi Node có thể có một hoặc nhiều Label để phân loại.
Một Node luôn có một định danh duy nhất (internal ID) và có thể chứa các thuộc tính (properties) dạng key-value.
1.2 Relationship (Quan hệ)
Relationship là liên kết có hướng giữa hai Node. Nó bao gồm 3 thành phần: Node nguồn (Start Node), Loại quan hệ (Type) và Node đích (End Node).
Quan hệ cũng có thể chứa thuộc tính, ví dụ: quan hệ "MUA" giữa "KHÁCH HÀNG" và "SẢN PHẨM" có thể có thuộc tính "ngay_mua" và "so_luong".
1.3 Property (Thuộc tính)
Property là dữ liệu mô tả chi tiết cho Node hoặc Relationship. Trong Neo4j, Property được lưu dưới dạng Map (dictionary) với kiểu dữ liệu: String, Integer, Float, Boolean, hoặc DateTime.
Việc hiểu rõ cấu trúc này giúp bạn hình dung cách dữ liệu được lưu trữ vật lý, từ đó tối ưu hóa việc truy vấn sau này.
2. Làm quen với Neo4j Browser
Neo4j Browser là giao diện web tích hợp sẵn, cho phép bạn nhập câu lệnh Cypher và xem kết quả dưới dạng đồ thị trực quan hoặc bảng dữ liệu.
2.1 Truy cập giao diện
Giả sử bạn đã chạy Neo4j Server trên Ubuntu 24.04 theo Phần 2. Default port là 7474 cho Browser và 7687 cho Bolt Protocol.
Mở trình duyệt trên máy chủ (hoặc máy khách nếu đã cấu hình firewall) và truy cập địa chỉ:
https://localhost:7474
Kết quả mong đợi: Giao diện đăng xuất hiện. Nhập username (mặc định là neo4j) và password (mã bạn đã đặt ở Phần 3) để đăng nhập.
2.2 Cấu trúc giao diện chính
Giao diện chia làm 3 khu vực chính:
- Command Input (Bên trái): Nơi bạn gõ câu lệnh Cypher. Có các nút như "Run" (chạy), "Cancel" (hủy), và "Clear" (xóa).
- Visualization (Giữa): Hiển thị dữ liệu dạng đồ thị (Graph). Bạn có thể kéo, phóng to, thu nhỏ các node.
- Result Table (Bên phải): Hiển thị dữ liệu dạng bảng, tương tự SQL, cho phép xem chi tiết các thuộc tính.
Để xóa dữ liệu cũ (nếu có) trước khi bắt đầu bài thực hành này, hãy chạy lệnh xóa toàn bộ:
MATCH (n) DETACH DELETE n
Kết quả mong đợi: Bảng thông báo bên phải hiển thị số lượng node và relationship đã bị xóa. Màn hình đồ thị trống trơn.
3. Cú pháp Cypher cơ bản
Cypher là ngôn ngữ truy vấn dành riêng cho Graph. Tên gọi bắt nguồn từ "Cipher" (mật mã), ám chỉ việc nó mô tả các mô hình đồ thị một cách trực quan.
3.1 Lệnh CREATE: Tạo dữ liệu
Cú pháp cơ bản để tạo một Node:
CREATE (n:Label {property1: value1, property2: value2})
Cú pháp để tạo Relationship giữa 2 Node đã tồn tại:
CREATE (a)-[:TYPE]->(b)
Trong đó:
(n:Label): Tạo node với nhãn "Label".
{key: value}: Gán thuộc tính cho node.
[:TYPE]: Định nghĩa loại quan hệ.
(a)-[:TYPE]->(b): Mũi tên chỉ hướng từ a đến b.
3.2 Lệnh MATCH: Tìm kiếm mô hình
MATCH hoạt động giống như WHERE trong SQL, nhưng thay vì lọc theo dòng, nó lọc theo cấu trúc đồ thị.
MATCH (n:Label) WHERE n.property = 'value'
Bạn có thể dùng MATCH để tìm một node đơn lẻ hoặc một đường đi phức tạp gồm nhiều node và relationship.
3.3 Lệnh RETURN: Trả về kết quả
Sau khi MATCH tìm thấy dữ liệu, bạn dùng RETURN để hiển thị nó. Nếu không có RETURN, Neo4j vẫn chạy nhưng không trả về gì.
MATCH (n:Person) RETURN n.name, n.age
Bạn có thể trả về toàn bộ node RETURN n hoặc chỉ các thuộc tính cụ thể. Có thể dùng alias (biệt danh) để đổi tên cột trong bảng kết quả.
4. Thực hành: Xây dựng mạng xã hội mẫu
Bây giờ chúng ta sẽ tạo một dataset nhỏ mô phỏng mạng xã hội với các người dùng (Person) và quan hệ bạn bè (KNOWS).
4.1 Tạo các Node (Người dùng)
Chúng ta sẽ tạo 3 người: Alice, Bob và Charlie, mỗi người có các thuộc tính khác nhau.
CREATE (alice:Person {name: 'Alice', age: 30, email: 'alice@example.com'}),
(bob:Person {name: 'Bob', age: 25, email: 'bob@example.com'}),
(charlie:Person {name: 'Charlie', age: 35, email: 'charlie@example.com'});
Kết quả mong đợi: Giao diện hiển thị 3 node tròn với nhãn "Person". Bảng bên phải hiện 3 dòng dữ liệu tương ứng với 3 node vừa tạo.
4.2 Tạo các Relationship (Quan hệ)
Tiếp theo, chúng ta tạo quan hệ "KNOWS" (biết nhau). Alice biết Bob, Bob biết Charlie, và Alice cũng biết Charlie.
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}), (c:Person {name: 'Charlie'})
CREATE (a)-[:KNOWS {since: 2020}]->(b),
(b)-[:KNOWS {since: 2021}]->(c),
(a)-[:KNOWS {since: 2019}]->(c);
Kết quả mong đợi: Các đường nối (cạnh) xuất hiện giữa các node. Mũi tên chỉ hướng từ người "biết" đến người "được biết". Bảng bên phải hiển thị 3 dòng relationship.
4.3 Truy vấn và kiểm chứng (Verify)
Bước này cực kỳ quan trọng để đảm bảo dữ liệu đã được lưu đúng mô hình.
Yêu cầu 1: Tìm tất cả mọi người và hiển thị tên, tuổi.
MATCH (p:Person) RETURN p.name AS Ten, p.age AS Tuoi
Kết quả mong đợi: Bảng hiện 3 dòng với cột "Ten" và "Tuoi" chứa đúng dữ liệu Alice, Bob, Charlie.
Yêu cầu 2: Tìm ai là bạn của Alice (quan hệ KNOWS từ Alice).
MATCH (a:Person {name: 'Alice'})-[:KNOWS]->(friend) RETURN friend.name AS Ban_cua_Alice
Kết quả mong đợi: Bảng hiện 2 dòng, đó là Bob và Charlie.
Yêu cầu 3: Tìm ai biết Bob (quan hệ KNOWS đến Bob).
MATCH (person)-[:KNOWS]->(b:Person {name: 'Bob'}) RETURN person.name AS Nguoi_biet_Bob
Kết quả mong đợi: Bảng hiện 2 dòng, đó là Alice và Charlie (vì Bob được cả 2 người này biết, dựa trên hướng mũi tên).
4.4 Thực hành nâng cao: Lọc theo thuộc tính của Relationship
Neo4j cho phép lọc dựa trên thuộc tính của đường nối, đây là điểm mạnh vượt trội so với SQL truyền thống.
Yêu cầu: Tìm những người Alice biết từ trước năm 2020.
MATCH (a:Person {name: 'Alice'})-[:KNOWS {since: 2019}]->(f) RETURN f.name
Kết quả mong đợi: Chỉ hiện 1 dòng là "Charlie", vì quan hệ với Charlie có thuộc tính since: 2019, còn Bob là 2020.
5. Tổng kết và dọn dẹp
Bạn vừa hoàn thành việc hiểu cấu trúc Node/Relationship, sử dụng Neo4j Browser và viết các câu lệnh Cypher cơ bản (CREATE, MATCH, RETURN).
Để chuẩn bị cho Phần 5 (Quản lý dữ liệu nâng cao), hãy xóa toàn bộ dataset mẫu này để bắt đầu với môi trường sạch.
MATCH (n) DETACH DELETE n
Kết quả mong đợi: Thông báo xóa thành công, số lượng node và relationship về 0. Màn hình trống.
Điều hướng series:
Mục lục: Series: Triển khai Database Graph với Neo4j và Ubuntu 24.04
« Phần 3: Cấu hình bảo mật, xác thực và truy cập Neo4j
Phần 5: Quản lý dữ liệu nâng cao và tối ưu hóa truy vấn »