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));
これは当たり前のルートですが、悪臭がします。クエリの結果、一連の OR ステートメントが Lucene に送信されます。Raven が処理できる上限は約 1024 であるため、1 人のユーザーが 1000 人を超える人をフォローすることはできません。
オプション 2 - フォロワーごとに 1 つの投稿
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 人のフォロワーを持っている場合、インデックスにとって問題になるでしょうか? すべてのユーザーにメッセージを投稿したい場合はどうすればよいでしょうか? おそらく別のアプローチがありますか?