2013-03-04 15 views
78

私は私のメインのスキーマ内のより深い層対サブ文書を使用しての長所と短所についての興味:マングースのサブ文書

var subDoc = new Schema({ 
    name: String 
}); 

var mainDoc = new Schema({ 
    names: [subDoc] 
}); 

または

var mainDoc = new Schema({ 
    names: [{ 
    name: String 
}] 
}); 

私は現在使用していますどこでもサブ文書を作成できますが、主にパフォーマンスやクエリーに関する問題が発生する可能性があります。

+0

私はこれに答えをタイプしようとしていましたが、どうやって見つけられませんでした。しかしここで見てください:http://mongoosejs.com/docs/subdocs.html – gustavohenke

+0

MongoDBのデータベーススキーマの作成時にあなた自身に尋ねる良い答えは、http:// stackoverflowです。com/questions/5373198/a-simple-mongodb-question-embed-or-reference – anthonylawson

+0

あなたは '_id'フィールドについても記述する必要がありますか?それが有効になっていれば、それは自動的なものではありませんか? – Vadorequest

答えて

42

the docsによれば、全く同じです。 しかし、スキーマを使用すると、_idフィールドも追加されます(無効にしていない限り)。おそらくサブドメインを追跡するためにさらにリソースを使用します。

代替宣言構文

新v3のであなたは、サブ文書スキーマのインスタンスにアクセスする必要がない場合は、単にオブジェクトリテラル[を渡すことによって、サブドキュメントを宣言してもよいです。 ..]

+0

しかし、私はこれを試しました。サブ文書データが別々のコレクションに格納されない理由常にmainDocコレクションの中に格納されます。 –

+16

これは、サブ文書の仕組みを示しています。それらは文書の内部に埋め込まれている。 Mongooseで遊ぶ前に、根本的なMongoDBを理解していることを確認してください。 – AndyL

+1

_idを追加するスキーマについては意味がありますが、サブ文書の配列とオブジェクトリテラルの配列を持つスキーマを作成し、_idを両方に追加しました。行動は変わったのか? –

10

私はこれがSOの複数の投稿によって他の場所で処理されていると思います。

わずか数:

大きなキーはかなり複雑なトレードオフのセットのみ、ここでは単一の答えがないことです。

+1

おそらく私は正しく私の質問を表現していない - これは私のデータベースを構造化すべきではなくむしろサブスキーマを使用する内部の深い層に配列を書く対の質問です。サブスキーマを使用する主な理由は、カスタムスキーマタイプを使用して検証することができることです。ネストされた配列では機能しません(以前の質問から)。サブディックはネストされた配列とほぼ同じですが、内部構造がわからない場合は、パフォーマンス上の問題などが発生します。 – cyberwombat

26

モデルのさまざまな部分で再利用されるスキーマがある場合は、子ドキュメントの個別のスキーマを定義して、自分自身を複製する必要はありません。

+2

素晴らしい答え。時には私は複数のサブモデルを1つのモデルで使用するか、区別する必要があるモデル内に同じサブ文書構造を持つ2つのフィールドを持っています。 –

+1

また、冗長な情報を保存する利点/欠点も考慮する必要があります。 –

8

静的ドキュメントまたはパフォーマンスに影響があるため数百を超えない埋め込みドキュメントを使用する必要があります。私はしばらく前にその問題について話を進めました。新しく、MongoDBのソリューションアーキテクトとして働いているAsya Kamskyは、 "サブドキュメントの使用"に関する記事を書いていました。

解決策やベストプラクティスを探している人に役立つことを願っています。

オリジナル投稿はhttp://askasya.com/post/largeembeddedarraysです。 あなたはすべてのhttps://stackoverflow.com/users/431012/asya-kamsky

まず彼女のStackOverflowのプロファイルに到達することができ、私たちは、このような なことをしたいと思う理由を考慮する必要があります。通常、私は人々に、彼らがこの文書をフェッチしているときにいつも取り戻したいことを埋め込むようにすることを勧めます。フリップフック の方が、返信したくない文書 に物を埋め込みたくないということです。

アクティビティを文書に埋め込むと、最初は でうまくいくでしょう。私の活動のすべてがそこにあり、1回の読み上げで、あなたが私に見せたいことをすべて返すことができるからです。最近 これをクリックしてここにあなたの最後の2つのコメントはありますか?しかし、何が起こるのですか?6ヶ月後に が来て、私は長いことを気にしません 前に、あなたは私にそれらを見せたくありません具体的には に行くいくつかの古い活動を探しですか?

最初に、大きくて大きなドキュメントを返すことになり、小さくて小さい部分について を気にすることになります。しかし、あなたは への投影を使用することができますいくつかの配列を返す、本当の痛みは、 ディスク上の文書が大きくなると、それはすべての場合でも読んでいる場合でも、 最後にそれを返すつもりです私の活動が有効である限り、私の活動は で止まっていないので、文書は伸び続けると伸び続けます。

この問題の最も顕著な問題は、最終的に16MBの 文書の制限に達することになりますが、これはまったく気にするべきことではありません。 についてです。継続的に成長する文書では、ディスクに再配置する必要があるたびに、より高い数値の が発生し、フラグメンテーションの影響を緩和するために の手順を実行しても、全体的に不必要な時間がかかり、全体的なパフォーマンスに影響します。 アプリケーション全体。

アプリケーションのパフォーマンスを完全に停止させるもう1つのことがあります。これは、ますます増加するこの アレイをインデックスすることです。その意味は、 という配列を持つ文書が毎回再配置されるたびに、 が更新される必要があるインデックスエントリの数は、その文書の のインデックス値の数に正比例し、その配列が大きければ大きいほどその番号は となります。

がデータモデルに適している場合は、配列を使用することを恐れたくありません。これは、文書データモデル の強力な機能ですが、強力なツールと同様に、適切な状況で を使用してください。注意して使用する必要があります。

+0

これは一番の答えです。それはお金に打撃を与える。 MongoDB自身の白書はほとんど同じことを言っています。 –

7

基本的には、変数nestedDovを作成し、簡易版ここname: [nestedDov]

をそれを置く:

var nestedDoc = new Schema({ 
    name: String 
}); 

var mainDoc = new Schema({ 
    names: [nestedDoc] 
}); 

JSON例

{ 
    "_id" : ObjectId("57c88bf5818e70007dc72e85"), 
    "name" : "Corinthia Hotel Budapest", 
    "stars" : 5, 
    "description" : "The 5-star Corinthia Hotel Budapest on the Grand Boulevard offers free access to its Royal Spa", 
    "photos" : [ 
     "/photos/hotel/corinthiahotelbudapest/1.jpg", 
     "/photos/hotel/corinthiahotelbudapest/2.jpg" 
    ], 
    "currency" : "HUF", 
    "rooms" : [ 
     { 
      "type" : "Superior Double or Twin Room", 
      "number" : 20, 
      "description" : "These are some great rooms", 
      "photos" : [ 
       "/photos/room/corinthiahotelbudapest/2.jpg", 
       "/photos/room/corinthiahotelbudapest/5.jpg" 
      ], 
      "price" : 73000 
     }, 
     { 
      "type" : "Deluxe Double Room", 
      "number" : 50, 
      "description" : "These are amazing rooms", 
      "photos" : [ 
       "/photos/room/corinthiahotelbudapest/4.jpg", 
       "/photos/room/corinthiahotelbudapest/6.jpg" 
      ], 
      "price" : 92000 
     }, 
     { 
      "type" : "Executive Double Room", 
      "number" : 25, 
      "description" : "These are amazing rooms", 
      "photos" : [ 
       "/photos/room/corinthiahotelbudapest/4.jpg", 
       "/photos/room/corinthiahotelbudapest/6.jpg" 
      ], 
      "price" : 112000 
     } 
    ], 
    "reviews" : [ 
     { 
      "name" : "Tamas", 
      "id" : "/user/tamas.json", 
      "review" : "Great hotel", 
      "rating" : 4 
     } 
    ], 
    "services" : [ 
     "Room service", 
     "Airport shuttle (surcharge)", 
     "24-hour front desk", 
     "Currency exchange", 
     "Tour desk" 
    ] 
} 

例:

enter image description here

+0

それはパフォーマンスの一つである質問には全く言及していません。 – cyberwombat

+0

私はもっと理にかなって少し編集しました。どう思いますか? –

+1

質問はネストされたスキーマの実行方法を尋ねていません。 Mongooseがネストされたスキーマや組み込みサブ文書でよりパフォーマンスが高いかどうかについての議論。基本的には、Mongooseが互いを好むベンチマークやソート、エッジケースを話しています。そして、選択された答えが言及しているように、少なくともV3からは何の違いも見られません。 – cyberwombat

関連する問題