580 votes

Relations de MongoDB : incorporer ou faire référence ?

Je suis nouveau sur MongoDB--à venir à partir d'une base de données relationnelle arrière-plan. Je veux concevoir une question de structure avec quelques commentaires, mais je ne sais pas quelle relation à utiliser pour les commentaires: - embed ou reference?

Une question avec certains commentaires, comme stackoverflow, aurait une structure comme ceci:

Question
    title = 'aaa'
    content = bbb'
    comments = ???

Au premier abord, je veux utiliser embeded commentaires (je pense que embed est recommandée dans MongoDB), comme ceci:

Question
    title = 'aaa'
    content = 'bbb'
    comments = [ { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'} ]

Il est clair, mais je suis inquiet à propos de cette affaire: Si je veux modifier un certain commentaire, comment puis-je obtenir de son contenu et de sa question? Il n'y a pas d' _id d'permettez-moi d'en trouver un, ni l' question_ref d'permettez-moi de trouver sa question. (Je suis débutant, je ne sais pas si il y a moyen de le faire sans _id et question_ref.)

Dois-je utiliser ref pas embed? Puis-je créer une nouvelle collection pour les commentaires?

820voto

John F. Miller Points 8033

C'est plus un art qu'une science. Les Mongo de la Documentation sur les Schémas est une bonne référence, mais voici quelques choses à considérer:

  • Mettre autant que possible

    La joie d'un Document de la base de données est qu'il élimine beaucoup de Jointures. Votre premier réflexe devrait être de place autant dans un seul document que vous le pouvez. Parce que MongoDB documents de structure, et parce que vous pouvez efficacement requête au sein de cette structure, il n'y a pas de besoin immédiat pour normaliser les données comme vous le feriez dans SQL. En particulier, toutes les données qui n'est pas utile en dehors de son document parent devrait faire partie d'un même document.

  • Séparer les données qui peuvent être référées à partir de plusieurs endroits dans sa propre collection.

    Ce n'est pas tellement un "espace de stockage" problème tel qu'il est "la cohérence des données" de l'émission. Si de nombreux dossiers de consulter les mêmes données, il est plus efficace et moins sujette aux erreurs de mettre à jour un enregistrement unique et de garder des références dans d'autres endroits.

  • Document de considérations relatives à la taille

    MongoDB impose un 4 MO (16 MO avec 1.8) limite de taille sur un seul document. Dans un monde de GO de données, cela semble petit, mais il est également 30 millions de tweets ou de 250 mille typique de Débordement de Pile réponses ou 20 scintillement des photos. D'autre part, c'est beaucoup plus de l'information que l'on peut vouloir à présent à la fois sur une page web typique. D'abord envisager ce qui va rendre vos requêtes plus facile. Dans de nombreux cas, la préoccupation au sujet des formats de documents sera optimisation prématurée.

  • Des structures de données complexes:

    MongoDB peut stocker arbitraire profondément imbriquée des structures de données, mais ne peut pas rechercher de manière efficace. Si vos données forme un arbre, une forêt ou un graphique, vous devez stocker chaque nœud et de ses bords dans un document distinct. (Note qu'il y a des magasins de données conçu spécifiquement pour ce type de données que l'on doit considérer aussi bien)

    Il a également été souligné qu'il est impossible de retourner un sous-ensemble d'éléments dans un document. Si vous avez besoin de pick-and-choisir quelques morceaux de chaque document, il sera plus facile de les séparer.

  • La Cohérence Des Données

    MongoDB fait un compromis entre l'efficacité et la cohérence. La règle est les modifications apportées à un document unique sont toujours atomique, tandis que les mises à jour plusieurs documents ne doivent jamais être considéré atomique. Il est également impossible de "verrouiller" un dossier sur le serveur (vous pouvez l'intégrer dans le client de la logique en utilisant par exemple un "verrou"). Lors de la conception de votre schéma d'envisager comment vous allez garder vos données cohérentes. En général, le plus que vous gardez dans un document le mieux.

Pour ce que vous décrivez, je voudrais intégrer les commentaires, et de donner à chaque commentaire un champ id avec un ObjectID. L'ObjectID a un horodatage intégrées, de sorte que vous pouvez l'utiliser à la place de créé en, si vous le souhaitez.

25voto

Silom Points 160

Eh bien, je suis un peu en retard, mais encore envie de partager ma façon de schéma la création.

J'ai des schémas pour tout ce qui peut être décrit en un mot, comme vous le feriez dans le classique de la programmation orientée objet.

E. G.

  • Commentaire
  • Compte
  • L'utilisateur
  • Article sur le blog
  • ...

Chaque schéma peuvent être enregistrés dans un Document ou un sous-document, donc je déclare ce pour chaque schéma.

Document:

  • Peut être utilisé comme une référence. (E. g. l'utilisateur fait un commentaire -> commentaire a "fabriqué par" référence pour l'utilisateur)
  • Est une "Racine" dans votre application. (E. g. l'article sur le blog -> il y a une page sur le blog)

Sous-document:

  • Peut être utilisé une seule fois / n'est jamais une référence. (E. g. Commentaire est enregistré dans l'article sur le blog)
  • N'est jamais une "Racine" dans votre application. (Le commentaire s'affiche dans l'article sur le blog de la page, mais la page est toujours à propos de l'article sur le blog)

24voto

Gates VP Points 26481

Si je veux éditer un commentaire spécifié, comment obtenir son contenu et sa question?

Vous pouvez interroger par sous-document: db.question.find({'comments.content' : 'xxx'}) .

Cela renverra le document entier de question. Pour éditer le commentaire spécifié, vous devez alors trouver le commentaire sur le client, effectuer l'édition et le sauvegarder dans la base de données.

En général, si votre document contient un tableau d'objets, vous trouverez que ces sous-objets devront être modifiés côté client.

15voto

Naren Dran Points 21

Oui, nous pouvons utiliser la référence dans le document.Pour remplir un autre document comme sql je l'ai rejoint.Dans mongo db elles n'ont pas joint à la cartographie de un à plusieurs " de la relation document.Au lieu de cela que nous pouvons utiliser les remplir de remplir notre scénario..

var mongoose = require('mongoose')
  , Schema = mongoose.Schema

var personSchema = Schema({
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Number, ref: 'Person' },
  title    : String,
  fans     : [{ type: Number, ref: 'Person' }]
});

La Population est le processus de remplacement automatique de chemins d'accès spécifiés dans le document par document(s) à partir d'autres de la collection(s). Nous pouvons remplir un document unique, de multiples documents, de la plaine de l'objet, de multiples objets simples, ou à tous les objets retournés par une requête. Regardons quelques exemples.

Mieux, vous pouvez obtenir plus d'informations, veuillez visiter :http://mongoosejs.com/docs/populate.html

14voto

finspin Points 971

Je sais que c'est assez ancien, mais si vous cherchez la réponse à la question de l'OP sur comment retourner un commentaire spécifié, vous pouvez utiliser l'opérateur $ (query) comme ceci:

 db.question.update({'comments.content': 'xxx'}, {'comments.$': true})
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X