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

親ドキュメントが存在しない可能性がある場合は、MongoDBサブドキュメントを更新します

    基本的に3つのケースがあります:

    1. 本とレビューの両方が存在します。これは単純な<​​code>$set
    2. 本は存在しますが、レビューはありません。これには$pushが必要です
    3. 本は存在しません。これには{upsert:1}が必要です および$setOnInsert

    障害が発生した場合にデータの整合性を損なうことなく、これらの2つを統合する方法を見つけることができませんでした(MongoDBにはアトミックトランザクションがないことを忘れないでください)。

    だから私の 最良のアイデアは次のとおりです:

    // Case 1:
    db.books.update({isbn:'1234567890',
                     review: { $elemMatch: {userID: '01234'}}},
                    {$set: {'review.$.rating': NEW_RATING}}
                   )
    
    // Case 2:
    db.books.update({isbn:'1234567890',
                     review: { $not: { $elemMatch: {userID: '01234'}}}},
                    {$push: {review: {rating: NEW_RATING, userID:'01234'}}}
                   )
    
    // Case 3:
    db.books.update({isbn:'1234567890'},
                    {$setOnInsert: {review: [{rating: NEW_RATING, userID:'01234'}]}},
                    {upsert:1}
                   )
    

    これらの3つの更新は、重複するケースがないため、生で盲目的に実行できます。すばらしいのは、これらすべての操作がべき等 であるということです。 。したがって、それらを1回または数回適用して、常に同じ結果を得ることができます。これは、フェイルオーバーの場合に特に重要です。さらに、DBに一貫性がなくなったり、既存のが失われたりすることはありません。 障害が発生した場合のデータ。最悪の場合、レビューはではありません 更新しました。最後に、これはすべき 同時更新の場合でもデータの一貫性を保証します(つまり、その場合、一方の更新でもう一方の更新が上書きされますが、同じ本の2つのドキュメント、または同じ本の同じユーザーの2つのレビューになることはありません)。
    ここでは遅いので、後で確認する必要があるので、私の分析はやや疑わしいかもしれません。

    最後に、MongoDBとアプリ間のラウンドトリップ数を減らしたい場合は、 update データベースコマンド 1つのコマンドで複数の更新をラップできます。




    1. $lookupの後に要素の配列として値を取得します

    2. moveChunkはデータ転送にTOシャードを使用できませんでした:新しいチャンクを受け入れることができません。

    3. HDFSチュートリアル–初心者向けのHDFSの完全な紹介

    4. MongoDB集約選択プロジェクト