как решить проблему "Digg" в MongoDB - PullRequest
3 голосов
/ 13 мая 2010

Некоторое время назад разработчик Digg опубликовал этот блог "http://about.digg.com/blog/looking-future-cassandra",, где он описал одну из проблем, которые не были оптимально решены в MySQL. Это было названо одной из причин их перехода к Cassandra.

Я играл с MongoDB, и я хотел бы понять, как

реализовать коллекции MongoDB для этой проблемы

Из статьи, схема для этой информации в MySQL:

CREATE TABLE `Diggs` (
  `id`      INT(11),
  `itemid`  INT(11),
  `userid`  INT(11),
  `digdate` DATETIME,
  PRIMARY KEY (`id`),
  KEY `user`  (`userid`),
  KEY `item`  (`itemid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `Friends` (
  `id`           INT(10) AUTO_INCREMENT,
  `userid`       INT(10),
  `username`     VARCHAR(15),
  `friendid`     INT(10),
  `friendname`   VARCHAR(15),
  `mutual`       TINYINT(1),
  `date_created` DATETIME,
  PRIMARY KEY                (`id`),
  UNIQUE KEY `Friend_unique` (`userid`,`friendid`),
  KEY        `Friend_friend` (`friendid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Эта проблема повсеместна в реализации сценариев социальных сетей. Люди дружат со многими людьми, и они, в свою очередь, много копают. Очень важно быстро показать пользователю, чем занимаются его друзья.

Я понимаю, что с тех пор несколько блогов предоставили чистое решение RDBM с индексами для этой проблемы; однако мне любопытно, как это можно решить в MongoDB.

Ответы [ 2 ]

1 голос
/ 14 мая 2010

Есть много возможных решений с монго. Вы все еще можете хранить diggs в таблице верхнего уровня (a.k.a. collection) как реляционная база данных, но дополнительно можете хранить diggs в виде массива в коллекции элементов или в коллекции пользователей. Аналогично, отношение «друг» может храниться в виде массива в пользовательской коллекции в прямом или обратном направлении.

Вероятно, самым простым подходом было бы множество копий в элементах и ​​множество друзей в пользователях. Затем за простым индексированным запросом для поиска друзей пользователя следует запрос «in» в индексированном поле items.diggs.userid.

Собственная документация Mongo об операторе $ in фактически использует этот пример.

1 голос
/ 14 мая 2010

Один из способов сделать это - добавить массив «друзей» к каждому сообщению.

{
  date: Date(...)
  friends: ['me', 'you', 'thatguy']
  ...
}
db.posts.ensureIndex({friends:1, date:-1})

Тогда вы можете легко отобразить мою страницу, выполнив это: db.posts.find({friends:'me'}).sort({date:-1})

Это будет работать до тех пор, пока у каждого пользователя менее 200 000 друзей; вам может понадобиться особый пост от пользователей с более чем этим. Одним из способов было бы просто разделить список друзей на несколько кусков по 100 000 и сделать одну запись в записи для каждого чанка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...