与RavenDB类似的Twitter模型

时间:2012-05-13 22:25:21

标签: asp.net-mvc document ravendb

我正在与Raven玩一下,试图找出为类似Twitter的场景建模对象的最佳方法。到目前为止,我已经提出了一些选择,但不确定哪一个是最好的。

public class User{
    public string Id{get;set;}
    public List<string> Following{get;set;}
    public List<string> Followers{get;set;}
}

User对象简单明了,只是一个ID和一系列ID,供我关注的人和跟随我的人使用。 Feed设置是我需要帮助的地方,从我关注的用户处获取所有帖子。

选项1 - 简单路线

这会根据用户ID搜索我关注的所有帖子。

public class Post{
    public string UserId{get;set;}
    public string Content{get;set;}
}

索引

public class Posts : AbstractIndexCreationTask<Post>{
    public Posts(){
        Map = results => from r in results
                         select new{
                             r.UserId
                         };
    }
}

查询

var posts = session.Query<Post,Posts>().Where(c=>c.UserId.In(peopleImFollowing));

这是显而易见的路线,但闻起来很糟糕。该查询导致发送给Lucene的一堆OR语句。 Raven将处理大约1024的上限,因此任何一个用户都不能超过1000人。

选项2 - 每个关注者的一个帖子

public class Post{
    public string UserId{get;set;}
    public string RecipientId{get;set;}
    public string Content{get;set;}
}

添加新帖子

foreach(string followerId in me.Followers){
   session.Store(new Post{
    UserId = me.UserId,
    RecipientId = followerId,
    Content = "foobar" });
}

这很容易理解,但很容易查询,但似乎会创建太多的文件......也许这无关紧要?

选项3 - 收件人列表

到目前为止,我最喜欢这个。

public class Post{
    public string UserId{get;set;}
    public List<string> Recipients{get;set;}
    public string Content{get;set;}
}

索引

public class Posts : AbstractIndexCreationTask<Post>{
    public Posts(){
        Map = results => from r in results
                         select new{
                             UserId = r.UserId,
                             Recipient = r.Recipients
                         }
    }
}

添加新帖子

session.Store(new Post{
               UserId = me.Id,
               Recipients = me.Followers,
               Content = "foobar"
              });

查询

var posts = session.Query<Post,Posts>().Where(c=>c.Recipient == me.Id);

这似乎是最好的方式,但我之前从未与Lucene合作过。如果有人拥有10,000名粉丝,这对索引会有问题吗?如果我们想发布一个发送给每个用户的消息怎么办?也许有另一种方法?

1 个答案:

答案 0 :(得分:1)

从我的角度来看,只有选项1确实有效,如果你想支持超过1024个用户,你可能想调整RavenDB如何与lucene对话。

选项2和选项3 没有考虑到在您关注新用户后,您希望他们的旧推文显示在您的时间轴中。同样,您还希望在取消关注后,这些推文会从您的时间轴中消失。如果你想用这两种方法中的一种来实现它,你需要在'follow'操作中复制它们的所有推文,并在'unfollow'上删除它们。这将使跟随/取消关注非常昂贵的操作,并且它也可能失败(如果包含部分推文的服务器在您执行此操作时不可用,该怎么办?)。

选项2 还有一个巨大的缺点,就是它会产生大量的重复数据。想想拥有数百万粉丝和数千个帖子的知名用户。然后将其与成千上万的着名用户相乘......甚至Twitter也无法处理这么多数据。

选项3 还存在这样的问题:对索引的查询变慢,因为每个lucene文档都有这个“收件人”字段,可能有数百万个值。你有数万亿的文件...不,我不是一个lucene专家,但我认为它不能足够快地显示时间线(甚至忽略你不是唯一想要显示时间线的并发用户)。

正如我上面所说,我认为只有选项1才有效。也许其他人有更好的方法。好问题顺便说一句。