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

MongoDBにデータを保存する効率的な方法:埋め込みドキュメントと個々のドキュメント

    急速に増加するコレクションは必要ないため、最初のアプローチ(個別のドキュメント)を使用し、可能であれば上限付きコレクションを使用することをお勧めします(mongoidは2.2で上限付きコレクションをサポートしますが、これは今週末にリリースされますI推測)。

    2番目のアプローチ(埋め込みドキュメント)では、最初にユーザーのルートドキュメントをフェッチしてから、アプリケーションで配列をトラバースして、探している投稿に関連するアクティビティを見つける必要があります。 Mongoidは、埋め込まれたドキュメントを見つける際の構文が類似しているため、すべてがdbで行われているように見える場合がありますが、実際には配列を反復処理します。

    クエリを実行する前にuser_id、activity_id、activity_typeがすでにあり、特定のアクティビティを探しているときにユーザーのアクティビティのリスト全体をdbから取得したくないので、最初のケースをお勧めします。アプリケーションでの計算(検索)がはるかに少なくなり、ネットワークトラフィックがはるかに少なくなります。

    個別のドキュメントのアプローチでは、user_id、activity_id、activity_typeにも一意のインデックスを作成すると便利です。それはあなたが文書の数を含むのを助けるでしょう。一意性の検証(追加のクエリ)を行うことができますが、一意のインデックスがある場合はほとんど不要です。検証の唯一の利点は、重複がある場合の検証エラーですが、セーフモードを維持しない限り、インデックスは重複するエントリをサイレントに無視します。

    過去のサイトアクティビティも保持する場合は、次のような構造にすることができます。

    class SiteActivity
      include Mongoid::Document
      include Mongoid::Timestamps
      belongs_to :user
      belongs_to :activity, polymorphic: true
    
      index [:user_id, :activity_id, :activity_type], :background => true, :unique => true
    
      field :last_access_time, :type => Time
      # last_access_times just here for history, not used
      field :last_access_times, :type => Array, :default => []
    end
    
    activity = SiteActivity.find_or_initialize_by(:user_id => current_user.id,
                   :activity_id => post.id, :activity_type => post.class)
    time = Time.now.utc
    activity.last_access_time = time
    activity.last_access_times << time
    activity.save
    


    1. MongoDB集計クエリの複雑さの評価:$lookupのコスト

    2. マングースを区別して使用し、スキップして一緒に制限する方法

    3. MongoDB 3.6.22008R2Plusがインストールされない

    4. mongoでトランザクションのロールバックを実現するにはどうすればよいですか?