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

Ứng dụng giống Twitter sử dụng MongoDB

Bạn có hai cách khả thi để một người dùng có thể theo dõi một người dùng khác; trực tiếp hoặc gián tiếp thông qua một nhóm, trong trường hợp đó, người dùng trực tiếp theo nhóm. Hãy bắt đầu với việc lưu trữ những trực tiếp này quan hệ giữa người dùng và nhóm:

{
  _id: "userA",
  followingUsers: [ "userB", "userC" ],
  followingGroups: [ "groupX", "groupY" ]
}

Bây giờ, bạn sẽ muốn có thể nhanh chóng tìm hiểu những người dùng mà người dùng A đang theo dõi, trực tiếp hoặc gián tiếp. Để đạt được điều này, bạn có thể không chuẩn hóa các nhóm mà người dùng A đang theo dõi. Giả sử nhóm X và Y được xác định như sau:

{
  _id: "groupX",
  members: [ "userC", "userD" ]
},
{
  _id: "groupY",
  members: [ "userD", "userE" ]
}

Dựa trên các nhóm này và quan hệ trực tiếp mà người dùng A có, bạn có thể tạo đăng ký giữa những người dùng. (Các) nguồn gốc của một đăng ký được lưu trữ với mỗi đăng ký. Đối với dữ liệu ví dụ, các đăng ký sẽ trông như thế này:

// abusing exclamation mark to indicate a direct relation
{ ownerId: "userA", userId: "userB", origins: [ "!" ] },
{ ownerId: "userA", userId: "userC", origins: [ "!", "groupX" ] },
{ ownerId: "userA", userId: "userD", origins: [ "groupX", "groupY" ] },
{ ownerId: "userA", userId: "userE", origins: [ "groupY" ] }

Bạn có thể tạo các đăng ký này khá dễ dàng, bằng cách sử dụng lệnh gọi rút gọn bản đồ cho một người dùng cá nhân. Nếu một nhóm được cập nhật, bạn chỉ phải chạy lại map-Reduce cho tất cả người dùng đang theo dõi nhóm và các đăng ký sẽ được cập nhật lại.

Thu nhỏ bản đồ

Các hàm thu nhỏ bản đồ sau sẽ tạo đăng ký cho một người dùng.

map = function () {
  ownerId = this._id;

  this.followingUsers.forEach(function (userId) {
    emit({ ownerId: ownerId, userId: userId } , { origins: [ "!" ] });
  });

  this.followingGroups.forEach(function (groupId) {
    group = db.groups.findOne({ _id: groupId });

    group.members.forEach(function (userId) {
      emit({ ownerId: ownerId, userId: userId } , { origins: [ group._id ] });
    });
  });
}

reduce = function (key, values) {
  origins = [];

  values.forEach(function (value) {
    origins = origins.concat(value.origins);
  });

  return { origins: origins };
}

finalize = function (key, value) {
  db.subscriptions.update(key, { $set: { origins: value.origins }}, true);
}

Sau đó, bạn có thể chạy map-Reduce cho một người dùng, bằng cách chỉ định một truy vấn, trong trường hợp này là cho userA .

db.users.mapReduce(map, reduce, { finalize: finalize, query: { _id: "userA" }})

Một số lưu ý:

  • Bạn nên xóa các đăng ký trước đó của một người dùng trước khi chạy map-Reduce cho người dùng đó.
  • Nếu cập nhật một nhóm, bạn nên chạy map-Reduce cho tất cả những người dùng theo dõi nhóm.

Tôi nên lưu ý rằng các chức năng thu nhỏ bản đồ này hóa ra phức tạp hơn những gì tôi nghĩ , bởi vì MongoDB không hỗ trợ mảng dưới dạng giá trị trả về của hàm giảm. Về lý thuyết, các chức năng could đơn giản hơn nhiều, nhưng sẽ không tương thích với MongoDB. Tuy nhiên, giải pháp phức tạp hơn này có thể được sử dụng để giảm thiểu toàn bộ users thu thập trong một cuộc gọi, nếu bạn phải làm như vậy.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cảnh báo ngừng sử dụng mongoDB mongoose

  2. Làm tròn đến 2 chữ số thập phân bằng cách sử dụng khung tổng hợp MongoDB

  3. Kết hợp toàn văn với chỉ mục khác

  4. Web Scraping và Crawling với Scrapy và MongoDB

  5. MongoDB find ()