web-dev-qa-db-fra.com

Sous-documents Mongoose vs schéma imbriqué

Je suis curieux de savoir les avantages et les inconvénients de l'utilisation de sous-documents par rapport à une couche plus profonde de mon schéma principal:

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

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

ou

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

J'utilise actuellement des sous-documents partout, mais je m'interroge principalement sur les problèmes de performances ou d'interrogation que je pourrais rencontrer.

106
cyberwombat

Selon la documentation , c'est exactement la même chose. Cependant, utiliser un schéma ajouterait un _id également (dans la mesure où cela n’a pas été désactivé) et utilise probablement davantage de ressources pour le suivi des sous-documents.

Autre syntaxe de déclaration

Nouveau dans la v3 Si vous n'avez pas besoin d'accéder à l'instance de schéma de sous-document, vous pouvez également déclarer des sous-documents en passant simplement un objet littéral [...]

59
AndyL

Si vous avez des schémas réutilisés dans différentes parties de votre modèle, il peut être utile de définir des schémas individuels pour la documentation enfant afin de ne pas avoir à vous dupliquer.

36
sonstone

Vous devez utiliser des documents incorporés s’il s’agit de documents statiques ou de plusieurs centaines uniquement en raison de leur impact sur les performances. Je suis passé par là à ce sujet depuis un moment. Récemment, Asya Kamsky, qui travaille comme architecte de solutions pour MongoDB, avait écrit un article sur "l’utilisation de sous-documents".

J'espère que cela aidera à qui cherche des solutions ou la meilleure pratique.

Article original sur http://askasya.com/post/largeembeddedarrays . Vous pouvez accéder à son profil stackoverflow sur https://stackoverflow.com/users/431012/asya-kamsky

Tout d’abord, nous devons examiner pourquoi nous voudrions faire une telle chose. Normalement, je conseillerais aux personnes d'intégrer des éléments qu'elles souhaitent toujours obtenir lorsqu'elles récupèrent ce document. Le revers de la médaille, c'est que vous ne voulez pas incorporer d'éléments dans le document que vous ne voulez pas revenir avec.

Si vous intégrez l'activité que j'exécute dans le document, cela fonctionnera très bien au début, car toute mon activité se déroule là et en une seule lecture, vous pouvez récupérer tout ce que vous voudrez peut-être me montrer: "vous avez récemment cliqué sur ce lien et ici. sont vos deux derniers commentaires "mais que se passe-t-il après six mois et que je me fiche de ce que j'ai fait il y a longtemps et que vous ne voulez pas me les montrer à moins que je ne cherche spécifiquement une activité ancienne?"

Tout d’abord, vous finirez par retourner un document de plus en plus gros et en prendrez soin d’une portion de plus en plus petite. Mais vous pouvez utiliser projection pour ne renvoyer qu’une partie du tableau. La vraie difficulté, c’est que le document sur disque s’agrandisse et qu’il reste lu, même si vous n’en restez qu’une partie à l’utilisateur final. étant donné que mon activité ne va pas s'arrêter tant que je suis actif, le document continuera à se développer.

Le problème le plus évident avec cela est que vous atteindrez éventuellement la limite de 16 Mo de documents, mais ce n'est pas du tout ce qui devrait vous préoccuper. Un document dont la taille ne cesse de croître entraîne des coûts croissants chaque fois qu'il doit être déplacé sur disque. Même si vous prenez des mesures pour atténuer les effets de la fragmentation, vos écritures seront généralement inutilement longues, ce qui affectera les performances globales de votre application.

Il existe une dernière chose que vous pouvez faire qui gênera complètement les performances de votre application: l’indexation de ce tableau de plus en plus important. Cela signifie que chaque fois que le document contenant ce tableau est déplacé, le nombre d'entrées d'index devant être mis à jour est directement proportionnel au nombre de valeurs indexées dans ce document. Plus le tableau est grand, plus ce nombre est grand. être.

Je ne veux pas que cela vous effraie d'utiliser des tableaux lorsqu'ils conviennent au modèle de données. Ils constituent une fonctionnalité puissante du modèle de données de la base de données. Cependant, comme tous les outils puissants, il doit être utilisé dans les bonnes circonstances. et il devrait être utilisé avec précaution.

21
efkan

Fondamentalement, créez une variable nestedDov et mettez-la ici name: [nestedDov]

Version simple:

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

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

Exemple 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"
    ]
}

Exemple:

enter image description here

13
Wayne Chiu

Je pense que cela est géré ailleurs par plusieurs postes sur SO.

Juste un peu:

La grande clé est qu'il n'y a pas de réponse unique ici, seulement un ensemble de compromis assez complexes.

9
Gates VP