web-dev-qa-db-ja.com

Mongooseサブドキュメントとネストされたスキーマ

私は、サブドキュメントを使用することの長所と短所と、メインスキーマのより深い層について興味があります。

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

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

または

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

私は現在、どこでもサブドキュメントを使用していますが、主にパフォーマンスやクエリの問題について疑問に思っています。

106
cyberwombat

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

代替宣言構文

v3の新機能サブドキュメントスキーマインスタンスにアクセスする必要がない場合は、オブジェクトリテラルを渡すだけでサブドキュメントを宣言することもできます[...]

59
AndyL

モデルのさまざまな部分で再利用されるスキーマがある場合、子ドキュメントの個々のスキーマを定義して、自分で複製する必要がないようにすると便利です。

36
sonstone

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

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

http://askasya.com/post/largeembeddedarrays の元の投稿 https://stackoverflow.com/users/431012/asya-kamsky で彼女のstackoverflowプロファイルにアクセスできます。

まず、なぜそんなことをしたいのかを考えなければなりません。通常、私は人々がこのドキュメントを取得するときに常に取り戻したいものを埋め込むことを勧めます。これの裏側は、ドキュメントに戻したくないものをドキュメントに埋め込みたくないということです。

私がドキュメントに実行するアクティビティを埋め込むと、最初はうまくいきます。アクティビティはすべてそこにあるので、一度読むだけで、見せたいすべてのものを取り戻すことができます。 「最後の2つのコメントはありますか?」しかし、6か月後に何が起こりますか?私はずっと前にやったことを気にしませんし、特に古いアクティビティを探しに行かない限り、それらを見せたくないですか?

最初に、より大きなドキュメントを返して、その小さな部分に注意を払うことになります。ただし、プロジェクションを使用して配列の一部のみを返すことができます。本当の痛みは、ディスク上のドキュメントが大きくなり、エンドユーザーにその一部だけを返す場合でも、すべてが読み取られることです。私が活動している限り私の活動は止まらないので、文書は成長し続けます。

これに関する最も明白な問題は、最終的には16MBのドキュメント制限に達することですが、心配する必要はまったくありません。継続的に成長するドキュメントは、ディスクに再配置するたびにますますコストがかかります。断片化の影響を軽減するための措置を講じたとしても、書き込みは全体的に不必要に長くなり、アプリケーション全体のパフォーマンスに影響を与えます。

アプリケーションのパフォーマンスを完全に損なうことができるもう1つの方法があります。それは、この増え続ける配列にインデックスを付けることです。つまり、この配列を持つドキュメントが再配置されるたびに、更新する必要があるインデックスエントリの数は、そのドキュメント内のインデックス付き値の数に正比例し、配列が大きいほど、その数は大きくなりますである。

データモデルに適している配列を使用することでこれを怖がらせたくありません-配列はドキュメントデータベースデータモデルの強力な機能ですが、すべての強力なツールと同様に、適切な状況で使用する必要があります慎重に使用する必要があります。

21
efkan

基本的に、変数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

13
Wayne Chiu

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

少しだけ:

大きな鍵は、ここには単一の答えはなく、かなり複雑なトレードオフのセットだけであるということです。

9
Gates VP