Hỏi về cách làm hệ thống comment như viblo
Chào mọi người,
Mình đang làm một trang mạng xã hội như một cách để luyện kĩ năng. Trong project này mình sử dụng Django cho phía Backend và Angular 7 cho phía Frontend. Hiện tại mình đang cần tìm cách để tạo ra mội hệ thống comment giống như viblo, có thể reply comment liên tục và hiển thị dưới dạng hình cây.
Mình có nghĩ ra ý tưởng là có thể tạo ra một bảng với 2 column là parent và content, ví dụ như bảng dưới đây:
id | parent | content |
---|---|---|
1 | null | First comment |
2 | 1 | Child of first comment |
Tuy nhiên khi dùng cách này thì việc query khi lấy content rất chậm, vì cứ phải lặp đi lặp lại để tìm child của parent. Mình đã thử search trên mạng xem có thuật toán nào ứng dụng cho hệ thống comment này không tuy nhiên chưa đúng keyword nên chưa tìm được. Vì vậy mình post câu hỏi này mong được mọi người giúp đỡ và chỉ giúp mình thuật toán hoặc keywords để giải quyết vấn đề này.
Mọi người xem giúp mình với ạ. Mình cảm ơn!
4 CÂU TRẢ LỜI
Không biết bạn đang dùng DBMS nào nhỉ? Như bạn nói, mấu chốt của bạn là gặp vấn đề khi query comments ra bị chậm. Bạn có thể thử như sau:
- Mỗi comment mình sẽ lưu id của bài viết được comment (mình gọi là
commentable_id
nha). Khi try vấn chỉ cần thêm ràng buộcwhere('commentable_id', postID)
là lấy được tất cả các comments của một bài viết. - Nếu làm kiểu comment đa cấp, bạn có thể lưu thêm
parent_id
, sau khi truy vấn xong ở bước 1 lấy được tất cả comments, mình xử lý gộp chúng bằng code Python cũng được. Làm kiểu này nếu hệ thống có ít comment. Còn như facebook thì họ chỉ làm 2 cấp. Ở cấp thứ 2 họ chỉ select ra mấy cái mới nhất mà thôi. - Nếu bạn muốn tiện truy vấn trong khi làm comment đa cấp, có thể thêm một trường
path
, có format:child_path
=parent_path
+child_id
VD: Comment 0003 reply cho comment 0002, comment 0002 thì lại reply cho comment 0001 tạo thành 3 cấp độ. Cáipath
tương ứng của các comment là:- 0001 => 0001
- 0002 => 0001.0002
- 0003 => 0001.0002.0003
Lúc này mình có thể query theo regex: comments.path ^= 0001
thì sẽ lấy được tất cả comments của 0001
.
Làm nested comment như trang xem bài viết của Viblo cũng được nhưng chắc bạn nên cải tiến việc hiển thị comments theo một cách khác. Hiển thị như Viblo không phải là một cách hay, khi mà có quá nhiều cấp độ dẫn tới việc hiển thị theo dạng cây rất tệ về UI/UX. Giống như Callback Hell
trong javascript vậy.
Bài viết rất chi tiết, đúng cái mình cần, cảm ơn bác ạ
Bạn cần lưu thêm path cho mỗi comment nữa Bạn tham khảo link này nhé: https://dba.stackexchange.com/questions/191160/list-parent-then-nested-child-items-in-a-single-table
nếu như viblo thì chả cần nested set đâu, cứ thêm cái trường parent, thêm trường path, path thì gen ra khi insert comment
Bạn tham khảo mô hình cây nhị phân việc query sẽ cải thiện đáng kể đó.