[RedisGraph 3] Làm quen với ngôn ngữ Cypher
Cypher là gì?
Hiểu đơn giản, Cypher là ngôn ngữ truy vấn đồ thị.
Nó được sử dụng để truy vấn một số loại cơ sở dữ liệu đồ thị như RedisGraph, Neo4j. Điều này đồng nghĩa với việc, bạn chỉ cần học nó một lần và dùng cho nhiều loại cơ sở dữ liệu khác nhau. Có thể tham khảo thêm ở đây:
https://opencypher.org/projects/
Bắt đầu với Cypher
Nhìn từ bảng trên, ta thấy Cypher cũng tương đối dễ hiểu.
- Graph tương đương với một cơ sở dữ liệu.
- Một tập hợp Node Label/Relationship tương đương đương với Bảng.
- Node tương đương với một dòng(Row).
- ....
Nói chung, chúng (ý chỉ Cypher và SQL) có những khái niệm tương đương nhau nhưng không giống nhau hoàn toàn. Đừng hiểu lầm.
Cú pháp của Cypher
Định dạng nút (nodes)
- (varname:NodeName): Nút có nhãn là NodeName, tên biến của nút là varname. Nút có thể không có tên biến.
- Node có thể có nhiều nhãn, khi đó nó sẽ trông như thế này: (varname:NodeName1:NodeName2)
- (): nút rỗng
- Gợi ý sử dụng cách đặt tên nhãn theo kiểu CamelCase(viết hoa chữ cái đầu).
- Nên đặt tên nhãn mang tính gợi nhớ tới đối tượng, nhãn nút nên là một danh từ.
- Tên nhãn có phân biệt chữ hoa chữ thường.
Định dạng quan hệ (relationship)
- [varname:RELATIONSHIP_NAME]: mối quan hệ có nhãn là RELATIONSHIP_NAME và biến quan hệ là varname.
- Gợi ý cách đặt tên nhãn theo kiểu upper_case, tất cả được viết hoa và sử dụng dấu gạch nối giữa các từ.
- Nhãn của các quan hệ nên là động từ. Tên nhãn có phân biệt chữ hoa chữ thường.
Khóa thuộc tính, biến, tham số, bí danh và hàm
- Ví dụ: title, size(), count(), firstName...
- Có phân biệt chữ hoa chữ thường.
Nên viết theo định dạng camelCase(chữ cái đầu viết thường).
Mệnh đề
- Ví dụ:
MATCH
,WHERE
,WITH
,UNWIND
... - Các mệnh đề không phân biệt chữ hoa chữ thường.
Các mệnh đề nên được tạo kiểu là tất cả các chữ in hoa, được đặt ở đầu mỗi dòng để dễ đọc và dễ truy vấn.
Keyword
- Ví dụ:
AND
,OR
,IN
,NOT
,DISTINCT
,STARTS WITH
,CONTAINS
,ENDS WITH
,... - Các keyword không phân biệt chữ hoa chữ thường.
Nên được viết in hoa, không cần đặt ở đầu dòng mới.
Thụt dòng và ngắt dòng
- Mỗi mệnh đề nên được ngắt dòng, ngoài ra, các khối truy vấn con, ON CREATE, ON MATCH nên được ngắt dòng và thụt vào 2 khoảng trắng.
- Sử dụng dấu ngoặc nhọn để nhóm khối truy vấn con. Nếu truy vấn con chỉ có 1 dòng, không cần đặt nó xuống dòng riêng hoặc thụt lề.
Metacharacter
- Dấu nháy đơn: nên dùng cho các giá trị chuỗi bằng chữ.
- Ví dụ: 'Mats\' quote: "statement" ', "Cypher's a nice language"
Backticks ``
- Dùng để tránh thoát các ký tự có khoảng trắng hoặc ký tự đặc biệt.
- Ví dụ: MATCH (`odd-ch@racter$`:`Spaced Label` {`&property`: 42})
Dấu chấm phẩy
- Dùng trong trường hợp có 1 tập các câu lệnh Cypher và cần phân tách giữa các lệnh. Không nên dùng khi chỉ có 1 lệnh.
Giá trị null và boolean
- Nên được viết thường trong truy vấn.
- Ví dụ: p.birthday = null, missingBirth = true
Xử lý các mẫu
- Nếu một mẫu(pattern) bị tràn dòng, nên ngắt dòng sau mũi tên, không phải trước. Ví dụ:
MATCH (:Person)--(:Company)-->
(:Country)
- Sử dụng các nút và mối quan hệ ẩn danh nếu không được sử dụng sau này trong truy vấn. Ví dụ:
MATCH (:Person)-[:Likes]->
(technology:Technology)
RETURN technology
- Các mẫu nên nối với nhau để tránh lặp lại biến.
- Các nút được đặt tên hoặc các điểm chung nên được đặt ở đầu mệnh đề MATCH. Các mối quan hệ mẫu đi (-->) nên để trước các mối quan hệ mẫu đến (<--)
Khoảng trắng
- Không nên để khoảng trắng giữa không gian vị từ nhãn. Không có khoảng trắng giữa các mẫu.
- Một khoảng trắng ở hai bên toán tử. Một khoảng trắng sau dấu phẩy.
- Không nên để khoảng trắng giữa 2 dấu ngoặc đơn.
- Dùng khoảng trắng giữa truy vấn con và dấu ngoặc nhọn.
Thực hành sử dụng Cypher
Cách chạy Cypher trên RedisInsight
Bước 1: Chọn Database mà bạn muốn tương tác với nó. Cụ thể là một database test ta đã kết nối ở bài [1].
Bước 2: Mở Workbench- giao diện để người dùng gõ lệnh và tương tác với cơ sở dữ liệu.
Để chạy các câu lệnh Cypher trên RedisInsight, bạn sẽ cần thực hiện theo cú pháp:
# Cú pháp
GRAPH.QUERY [tên_của_graph] "[nội_dung_câu_lệnh]"
# Ví dụ:
GRAPH.QUERY FilmIndustry "CREATE (:Film { name: 'Force 10 from Navarone', released: 1978 })"
# trong đó:
# tên_của_graph là FilmIndustry
# nội_dung_câu_lệnh là CREATE (:Film { name: 'Force 10 from Navarone', released: 1978 })
Một số câu lệnh Cypher
Tạo node trống
create (n)
Tạo node có label
create (n:User)
Tìm những node có label
match (n) where n:User return n
Gán thêm label cho node
match (n) where id(n) in [173] set n:Supporter return n
Loại bỏ label khỏi node
match (n) where id(n) in [173] remove n:Supporter return n
Đếm số lượng node
match (n) return count(n)
Liệt kê tất cả label của các node
match (n) return labels(n)
Liệt kê tất cả label không trùng lặp của các node
match (n) return distinct labels(n)
Đếm tất cả các node có label không trùng lặp
match (n) return distinct count(labels(n))
Đếm tất cả các node và phân loại theo label không trùng lặp
match (n) return distinct count(labels(n)), labels(n)
Liệt kê tất cả label của một node
match (n) where id(n)=0 return labels(n)
Xóa node có label
match (n) where n:User:Admin delete n
Tạo node có property
create (n:Book{title: "Ký sự đường đời", author: "Trịnh Hải Châu"}) return n
Ví dụ về cách đặt tên cho property trong Cypher
# Có phân biệt hoa thường
create (n:Book{title: "Ký sự đường đời", author: "Trịnh Hải Châu", Author: "Trịnh Lan Chi"}) return n
# Sau khi thực thi câu lệnh này, sẽ có cùng lúc 2 thuộc tính author và Author cùng tồn tại trên một node.
#######################################
# Khi property là một chuỗi, nó phải đặt trong cặp `...`
create (n:Book{title: "Ký sự đường đời", author: "Trịnh Hải Châu", `đồng tác giả`: "Trịnh Lan Chi"}) return n
Bạn có học thêm về các cú pháp Cypher thông qua các bài toán cụ thể ở những phần tiếp theo.