sql >> データベース >  >> NoSQL >> MongoDB

ユーザー評価のスキーマ-Key/Value DB

    まず第一に、「ユーザークラスの辞書」は良い考えではありません。なぜ?追加のレートオブジェクトを追加するには、新しいアイテムを配列にプッシュする必要があります。これは、古いアイテムが削除されることを意味します。この挿入は、いわゆる「ドキュメントの移動」です。 "。ドキュメントの移動は遅く、MongoDBは空のスペースの再利用があまり得意ではないため、ドキュメントを大量に移動すると、大量の空のデータファイルが生成される可能性があります(「MongoDBTheDefinitiveGuide」ブックの一部のテキスト)。

    次に、正しい解決策は何ですか。Blogsという名前のコレクションがあり、ブログ投稿の評価ソリューションを実装し、さらにすべてのユーザーベースの評価操作を追跡するとします。

    ブログドキュメントのスキーマは次のようになります。

    {
       _id : ....,
       title: ....,
       ....
       rateCount : 0,
       rateValue : 0,
       rateAverage: 0
    }
    

    このドキュメントスキーマを含む別のコレクション(レート)が必要です:

    {
        _id: ....,
        userId: ....,
        postId:....,
        value: ..., //1 to 5
        date:....   
    }
    

    そして、そのための適切なインデックスを定義する必要があります:

    db.Rates.ensureIndex({userId : 1, postId : 1})// very useful. it will result in a much faster search operation in case you want to check if a user has rated the post previously

    ユーザーが評価したい場合は、まず、ユーザーが投稿を評価したかどうかを確認する必要があります。ユーザーが'user1'であると想定します 、クエリは次のようになります

    var ratedBefore = db.Rates.find({userId : 'user1', postId : 'post1'}).count()
    

    そしてratedBeforeに基づく 、 !ratedBeforeの場合 次に、新しいレートドキュメントをレートコレクションに挿入し、ブログのステータスを更新します。そうしないと、ユーザーは評価できません

    if(!ratedBefore)
    {
        var postId = 'post1'; // this id sould be passed before by client driver
        var userId = 'user1'; // this id sould be passed before by client driver
        var rateValue = 1; // to 5
        var rate = 
        {       
           userId: userId,
           postId: postId,
           value: rateValue,
           date:new Date()  
        };
    
        db.Rates.insert(rate);
        db.Blog.update({"_id" : postId}, {$inc : {'rateCount' : 1, 'rateValue' : rateValue}});
    }
    

    次に、rateAverageはどうなりますか ?rateCountに基づいて計算することを強くお勧めします およびrateValue クライアント側では、rateAverageを簡単に更新できます mongoqueryを使用 、しかしあなたはそれをすべきではありません。なぜ?簡単な答えは次のとおりです。これは、クライアントがこの種の作業を処理するのに非常に簡単な作業であり、すべてのブログドキュメントを平均化するには、不要な更新操作が必要です。

    平均クエリは次のように計算されます:

    var blog = db.Blog.findOne({"_id" : "post1"});
    var avg = blog.rateValue / blog.rateCount;
    print(avg);
    

    このアプローチを使用すると、mongodbで最大のパフォーマンスが得られ、ユーザー、投稿、日付に基づいてすべてのレートを追跡できます。



    1. ローカルキーMONGODBを使用してデータ暗号化を有効にするとエラーが発生します

    2. 変数を値として使用する場合のPythonでのMongoクエリ

    3. MongoDB C ++、挿入時にISODate値を追加する方法

    4. JavaScriptで2つの日付から秒単位で差を取得する