Je suis nouveau sur MongoDB - issu d'une base de données relationnelle. Je veux concevoir une structure de questions avec quelques commentaires, mais je ne sais pas quelle relation utiliser pour les commentaires: embed
ou reference
?
Une question avec quelques commentaires, comme stackoverflow , aurait une structure comme celle-ci:
Question
title = 'aaa'
content = bbb'
comments = ???
Au début, je veux utiliser des commentaires intégrés (je pense que embed
c'est recommandé dans MongoDB), comme ceci:
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
C'est clair, mais je suis inquiet dans ce cas: si je veux éditer un commentaire spécifié, comment puis-je obtenir son contenu et sa question? Il n'y a rien _id
à me laisser en trouver un, ni question_ref
à me laisser trouver sa question. (Je suis tellement novice, que je ne sais pas s'il y a moyen de le faire sans _id
et question_ref
.)
Dois-je utiliser ref
non embed
? Ensuite, je dois créer une nouvelle collection de commentaires?
Réponses:
C'est plus un art qu'une science. La documentation de Mongo sur les schémas est une bonne référence, mais voici quelques éléments à considérer:
Mettez autant que possible
La joie d'une base de données de documents est qu'elle élimine beaucoup de jointures. Votre premier réflexe devrait être de mettre autant de documents que possible dans un seul document. Parce que les documents MongoDB ont une structure, et parce que vous pouvez interroger efficacement au sein de cette structure (cela signifie que vous pouvez prendre la partie du document dont vous avez besoin, donc la taille du document ne devrait pas vous inquiéter beaucoup), il n'y a pas de besoin immédiat de normaliser des données comme vous feriez en SQL. En particulier, toutes les données qui ne sont pas utiles en dehors de leur document parent doivent faire partie du même document.
Séparez les données qui peuvent être référencées à partir de plusieurs endroits dans sa propre collection.
Il ne s'agit pas tant d'un problème «d'espace de stockage» que d'un problème de «cohérence des données». Si de nombreux enregistrements font référence aux mêmes données, il est plus efficace et moins sujet aux erreurs de mettre à jour un seul enregistrement et de conserver des références à d'autres endroits.
Considérations sur la taille du document
MongoDB impose une limite de taille de 4 Mo (16 Mo avec 1,8) sur un seul document. Dans un monde de Go de données, cela semble petit, mais c'est aussi 30 000 tweets ou 250 réponses Stack Overflow typiques ou 20 photos scintillantes. D'un autre côté, il s'agit de bien plus d'informations que l'on ne voudrait présenter à la fois sur une page Web typique. Réfléchissez d'abord à ce qui facilitera vos requêtes. Dans de nombreux cas, les inquiétudes concernant la taille des documents seront une optimisation prématurée.
Structures de données complexes:
MongoDB peut stocker des structures de données imbriquées profondes arbitraires, mais ne peut pas les rechercher efficacement. Si vos données forment un arbre, une forêt ou un graphique, vous devez effectivement stocker chaque nœud et ses bords dans un document distinct. (Notez qu'il existe des magasins de données spécialement conçus pour ce type de données que l'on devrait également prendre en compte)
Il a également été souligné qu'il est impossible de renvoyer un sous-ensemble d'éléments dans un document. Si vous avez besoin de 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 efficacité et cohérence. La règle est que les modifications apportées à un seul document sont toujours atomiques, tandis que les mises à jour de plusieurs documents ne doivent jamais être considérées comme atomiques. Il n'y a également aucun moyen de "verrouiller" un enregistrement sur le serveur (vous pouvez l'intégrer dans la logique du client en utilisant par exemple un champ "verrouiller"). Lorsque vous concevez votre schéma, réfléchissez à la manière dont vous garderez vos données cohérentes. Généralement, plus vous conservez dans un document, mieux c'est.
Pour ce que vous décrivez, j'intégrerais les commentaires et donnerais à chaque commentaire un champ id avec un ObjectID. L'ObjectID a un horodatage intégré afin que vous puissiez l'utiliser au lieu de créé à si vous le souhaitez.
la source
En général, l'intégration est bonne si vous avez des relations un-à-un ou un-à-plusieurs entre les entités, et la référence est bonne si vous avez des relations plusieurs-à-plusieurs.
la source
Vous pouvez interroger par sous-document:
db.question.find({'comments.content' : 'xxx'})
.Cela renverra l'intégralité du document Question. Pour modifier le commentaire spécifié, vous devez ensuite rechercher le commentaire sur le client, effectuer la modification et l'enregistrer dans la base de données.
En général, si votre document contient un tableau d'objets, vous constaterez que ces sous-objets devront être modifiés côté client.
la source
Eh bien, je suis un peu en retard mais je voudrais quand même partager ma façon de créer un schéma.
J'ai des schémas pour tout ce qui peut être décrit par un mot, comme vous le feriez dans la POO classique.
PAR EXEMPLE
Chaque schéma peut être enregistré en tant que document ou sous-document, je le déclare donc pour chaque schéma.
Document:
Sous-document:
la source
Je suis tombé sur cette petite présentation tout en recherchant cette question par moi-même. J'ai été surpris de la qualité de la présentation, à la fois de l'info et de sa présentation.
http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents
Il résume:
la source
a lot
? 3? dix? 100? Quoilarge
? 1 Ko? 1 Mo? 3 champs? 20 champs? Qu'est-ce quesmaller
/fewer
?Je sais que c'est assez ancien mais si vous cherchez la réponse à la question de l'OP sur la façon de renvoyer uniquement le commentaire spécifié, vous pouvez utiliser l' opérateur $ (requête) comme ceci:
la source
Oui, nous pouvons utiliser la référence dans le document.Pour remplir un autre document comme sql i joins.In mongo db, ils n'ont pas de jointures pour mapper un à plusieurs documents de relation.Au lieu de cela, nous pouvons utiliser populate pour remplir notre scénario.
Le remplissage est le processus de remplacement automatique des chemins d'accès spécifiés dans le document par des documents provenant d'autres collections. Nous pouvons remplir un seul document, plusieurs documents, un objet simple, plusieurs objets simples ou tous les objets renvoyés par une requête. Regardons quelques exemples.
Mieux vous pouvez obtenir plus d'informations s'il vous plaît visitez: http://mongoosejs.com/docs/populate.html
la source
En fait, je suis assez curieux de savoir pourquoi personne n'a parlé des spécifications UML. En règle générale, si vous avez une agrégation, vous devez utiliser des références. Mais s'il s'agit d'une composition, le couplage est plus fort et vous devez utiliser des documents intégrés.
Et vous comprendrez rapidement pourquoi c'est logique. Si un objet peut exister indépendamment du parent, vous voudrez y accéder même si le parent n'existe pas. Comme vous ne pouvez simplement pas l'intégrer dans un parent inexistant, vous devez le faire vivre dans sa propre structure de données. Et s'il existe un parent, il suffit de les lier ensemble en ajoutant une référence de l'objet dans le parent.
Vous ne savez pas vraiment quelle est la différence entre les deux relations? Voici un lien les expliquant: Agrégation vs Composition en UML
la source
J'ai créé ce quiz comme référence pour savoir si vous devez utiliser l'un ou l'autre
http://indie-rok.github.io/embedded-vs-reference-mongo-db
la source
Si vous aviez gardé une trace du nombre de commentaires et de l'index du commentaire que vous vouliez modifier, vous pourriez utiliser l'opérateur point ( exemple SO ).
Vous pourriez faire f.ex.
(comme une autre façon de modifier les commentaires à l'intérieur de la question)
la source