MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Cách lập mô hình hệ thống bỏ phiếu thích với MongoDB

Bất kể bạn cấu trúc tài liệu tổng thể của mình như thế nào, về cơ bản vẫn có hai thứ bạn cần. Về cơ bản đó là thuộc tính cho "số lượng" và "danh sách" những người đã đăng "thích" của họ để đảm bảo không có bản sao được gửi. Đây là cấu trúc cơ bản:

{ 
    "_id": ObjectId("54bb201aa3a0f26f885be2a3")
    "photo": "imagename.png",
    "likeCount": 0
    "likes": []
}

Dù thế nào đi nữa, có một "_id" duy nhất cho "bài đăng ảnh" của bạn và bất kỳ thông tin nào bạn muốn, nhưng sau đó là các trường khác như đã đề cập. Thuộc tính "like" ở đây là một mảng và sẽ chứa các giá trị "_id" duy nhất từ ​​các đối tượng "người dùng" trong hệ thống của bạn. Vì vậy, mọi "người dùng" đều có số nhận dạng duy nhất của riêng họ ở đâu đó, trong bộ nhớ cục bộ hoặc OpenId hoặc thứ gì đó, nhưng là một số nhận dạng duy nhất. Tôi sẽ gắn bó với ObjectId cho ví dụ.

Khi ai đó gửi "thích" cho một bài đăng, bạn muốn đưa ra tuyên bố cập nhật sau:

db.photos.update(
    { 
        "_id": ObjectId("54bb201aa3a0f26f885be2a3"), 
        "likes": { "$ne": ObjectId("54bb2244a3a0f26f885be2a4") }
    },
    {
        "$inc": { "likeCount": 1 },
        "$push": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") }
    }
)

Bây giờ là $inc hoạt động ở đó sẽ tăng giá trị của "likeCount" theo số được chỉ định, vì vậy hãy tăng thêm 1. $push hoạt động thêm số nhận dạng duy nhất cho người dùng vào mảng trong tài liệu để tham khảo trong tương lai.

Điều quan trọng chính ở đây là ghi lại những người dùng đã bỏ phiếu và những gì đang xảy ra trong phần "truy vấn" của tuyên bố. Ngoài việc chọn tài liệu để cập nhật bằng "_id" duy nhất của nó, điều quan trọng khác là kiểm tra mảng "thích" đó để đảm bảo rằng người dùng bỏ phiếu hiện tại không ở trong đó.

Điều này cũng đúng với trường hợp ngược lại hoặc "loại bỏ" "like":

db.photos.update(
    { 
        "_id": ObjectId("54bb201aa3a0f26f885be2a3"), 
        "likes": ObjectId("54bb2244a3a0f26f885be2a4")
    },
    {
        "$inc": { "likeCount": -1 },
        "$pull": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") }
    }
)

Điều quan trọng chính ở đây là các điều kiện truy vấn đang được sử dụng để đảm bảo rằng không có tài liệu nào được chạm vào nếu tất cả các điều kiện không được đáp ứng. Vì vậy, số lượng sẽ không tăng lên nếu người dùng đã bỏ phiếu hoặc giảm nếu phiếu bầu của họ thực sự không còn xuất hiện tại thời điểm cập nhật.

Tất nhiên, sẽ không thực tế nếu đọc một mảng có vài trăm mục nhập trong một tài liệu trong bất kỳ phần nào khác của ứng dụng của bạn. Nhưng MongoDB cũng có một cách rất chuẩn để xử lý điều đó:

db.photos.find(
    { 
        "_id": ObjectId("54bb201aa3a0f26f885be2a3"), 
    },
    { 
       "photo": 1
       "likeCount": 1,
       "likes": { 
          "$elemMatch": { "$eq": ObjectId("54bb2244a3a0f26f885be2a4") }
       }
    }
)

Việc sử dụng $elemMatch này trong phép chiếu sẽ chỉ trả về người dùng hiện tại nếu họ có mặt hoặc chỉ là một mảng trống mà họ không có. Điều này cho phép phần còn lại của logic ứng dụng của bạn biết được liệu người dùng hiện tại đã đặt phiếu bầu hay chưa.

Đó là kỹ thuật cơ bản và có thể phù hợp với bạn, nhưng bạn nên lưu ý rằng các mảng nhúng không được mở rộng vô hạn và cũng có giới hạn cứng 16MB đối với tài liệu BSON. Vì vậy, khái niệm này có vẻ đúng, nhưng không thể được sử dụng riêng nếu bạn đang mong đợi hàng nghìn lượt "bình chọn thích" cho nội dung của mình. Có một khái niệm được gọi là "bucketing" được thảo luận chi tiết trong ví dụ này về thiết kế Lược đồ kết hợp cho phép một giải pháp lưu trữ một lượng lớn "lượt thích". Bạn có thể nhìn vào đó để sử dụng cùng với các khái niệm cơ bản ở đây như một cách để thực hiện việc này ở mức độ lớn.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. $ tra cứu nhiều cấp độ mà không có $ unwind?

  2. Lập trình cơ sở dữ liệu Python với MongoDB cho người mới bắt đầu

  3. Các mảng được lưu trữ trong MongoDB có giữ thứ tự của chúng không?

  4. MongoDB $ bsonSize

  5. Cách nhận tất cả kết quả nếu trường unwind không tồn tại trong mongodb