我正在和 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 列表。提要设置是我需要帮助的地方,可以从我关注的用户那里获取所有帖子。
选项 1 - 简单的路线
这仅根据他们的 UserId 搜索我关注的人的所有帖子。
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 个关注者,那么索引会不会有问题?如果我们想向每个用户发布一条消息怎么办?也许还有另一种方法?