2

次のスキーマのどれがmongodbでの実装に最も効率的かを判断しようとしています。システム内の各ユーザーのフレンドIDと相互フレンド数を追跡する必要があります(user_idはコレクション全体で一意です)。友達の数は最大100,000人になる可能性があります。

スキーマ1

{
“_id” : “…”,
“user_id” : “1”,
friends : {
    “2” : {
        “id” : “2”,
        “mutuals” : 3
    }
     “3” : {
         “id” : “3”,
         “mutuals”: “1”
    }

   “4” : {
         “id” : “4”,
         “mutuals”: “5”
    }
}

}

スキーマ2

{
“_id” : “…”,
“user_id” : “1”,
friends : [
   {
        “id” : “2”,
        “mutuals” : 3
    },
    {
         “id” : “3”,
         “mutuals”: 1
    },
   {
         “id” : “4”,
         “mutuals”: 5
    }
]

}

要件

  1. user_idとfriendidが与えられた場合、友人IDが存在する場合は相互に1ずつインクリメントし、そうでない場合は相互に1の新しい友人を追加するようにドキュメントを更新します。
  2. user_idとfriendidが与えられた場合、friendが存在し、相互カウントが1より大きい場合は、相互カウントを1だけデクリメントするようにドキュメントを更新します。それ以外の場合は、ドキュメントからfriendを削除します。
  3. IDのリストを使用して、ドキュメントを検索し、存在するフレンドIDを特定します(これはクライアント側で実行できることですが、サーバー側のソリューションに関心があります)
  4. 上記を高速化するには、どのインデックスを使用する必要がありますか?

進行中の作業では、これの多くをスキーマ1で実装しましたが、スキーマ2ほど適切ではない可能性があることに気付き始めています。しかし、上記の質問に対して最も効率的な方法を見つけるのに苦労しています。

4

1 に答える 1

1

私の知る限り、ポイント1と2はmongoDBの単一のステートメントでは実行できません。特定の user_id、friend.id の組み合わせが存在するかどうかを確認するには、おそらく mongodb にクエリを実行する必要があります。そうである場合は更新し、そうでない場合はフレンド配列に追加します。以下の JavaScript コードを参照してください。

    use <dbname>;
    var FriendsList;
    var FriendId = "9";
    var UserId = "1";
    var Friends = db.Friends.findOne({"user_id":UserId, "friends.id":FriendId});
    if (Friends != null){ 
        print ("Friends is not null");
        FriendsList = Friends.friends;
        // print (FriendsList.toSource());
        for (var i = 0; i < FriendsList.length; i++){
            var curFriend = FriendsList[i];
            if (curFriend["id"] == FriendId){
                    curFriend["mutuals"] = curFriend["mutuals"] + 1;
                    FriendsList[i] = curFriend;
                    break;
                }
        }
    }
    if (Friends == null){
            print ("Friends is null");
            Friends = db.Friends.findOne({"user_id":UserId});
            FriendsList = Friends.friends;
            FriendsList.push({"id":FriendId, "mutuals":1});
            // print (FriendsList.toSource());
    }
        Friends.friends = FriendsList;
        db.Friends.save(Friends);

これを行うためのより良い方法を見つけたら、共有してください。

于 2012-11-29T12:14:34.887 に答える