2012-06-07 2 views
3

Je ne peux pas trouver « meilleure » solution pour le problème très simple (ou pas très)MongoDB: utilisateurs intégrés dans les commentaires

ont mis en classique des données: les messages qui sont attachées aux utilisateurs, les commentaires qui sont attachées à la poste et à l'utilisateur.

Maintenant, je ne peux pas décider comment construire régime/classes

Sur le chemin est de stocker user_id commentaires à l'intérieur et à l'intérieur.
Mais que se passe-t-il quand j'ai 200 commentaires sur la page?
Ou quand j'ai N messages sur la page?
Je veux dire qu'il devrait y avoir 200 demandes supplémentaires à la base de données pour afficher les informations utilisateur (comme le nom, avatar)

Une autre solution consiste à intégrer des données utilisateur dans chaque commentaire et chaque message. Mais d'abord -> il est énorme surcharge, deuxième -> système de système est corrompu (en utilisant mongoalchemy), troisième> utilisateur peut changer ses informations (comme avatar). Et quoi encore? Comme je comprends l'opération de mise à jour sur d'énormes collections de commentaires ou de messages n'est pas simple opération ...

Que suggéreriez-vous? Est-ce que 200 demandes par page à mongodb est OK (doit viser la performance)?

Ou peut-être que je suis juste manque quelque chose ...

Répondre

3

Vous pouvez éviter la N+1 -problem des centaines de requêtes à l'aide $in -queries. Considérez ceci:

Post { 
    PosterId: ObjectId 
    Text: string 
    Comments: [ObjectId, ObjectId, ...] // option 1 
} 

Comment { 
    PostId: ObjectId // option 2 (better) 
    Created: dateTime, 
    AuthorName: string, 
    AuthorId: ObjectId, 
    Text: string 
} 

Vous pouvez maintenant trouver les commentaires messages avec une requête $in, et vous pouvez trouver facilement tous les commentaires d'un auteur spécifique.

Bien sûr, vous pouvez également stocker les commentaires en tant que tableau incorporé dans la publication, et effectuer une requête $in sur les informations de l'utilisateur lorsque vous récupérez les commentaires. De cette façon, vous n'avez pas besoin de dé-normaliser les noms d'utilisateur et n'avez toujours pas besoin de centaines de requêtes.

Si vous choisissez de dénormaliser les noms d'utilisateur, vous devrez mettre à jour tous les commentaires déjà faits par cet utilisateur lorsqu'un utilisateur change, par ex. son nom. D'un autre côté, si de telles opérations ne se produisent pas très souvent, cela ne devrait pas être un gros problème. Ou peut-être que c'est encore mieux de stocker le nom que l'utilisateur avait quand il a fait le commentaire, en fonction de vos besoins.

Un problème général avec l'incorporation est que different writers will write to the same object, de sorte que vous devrez utiliser le atomic modifiers (tel que $push). C'est parfois plus difficile à utiliser avec les mappeurs (je ne connais pas la mongoalchimie), et généralement moins flexible.

+0

Actualy pour le moment mes commentaires juste comme ça, dans une collection séparée. La seule différence, je stocke post_id à l'intérieur du commentaire et non un tableau de commentaires à l'intérieur de la poste. Donc, quand le poste est lu, je fais une demande supplémentaire pour aller chercher les commentaires. Juste quelques questions pour être sûr de ce que vous voulez dire: 1) Avec votre schéma, cette requête devrait également être faite (en utilisant $ in au lieu de find par post_id)? 2) Est-ce que je comprends bien, que vous proposez d'analyser le tableau de commentaires qui devrait être affiché, de collecter les user_id's, puis de demander à tous les utilisateurs de $ supplémentaires? Donc, le total est de 3 demandes faites, peu importe le nombre de commentaires? – Tigra

+1

J'ai édité ma réponse pour clarifier. 'Commentaire' a maintenant un' PostId', ce que je pense est mieux. J'avais peur que votre schéma actuel soit basé sur l'intégration. Donc 1) non, "$ in" n'est pas requis, la requête standard est meilleure. 2) oui, vous devrez collecter des identifiants d'utilisateur uniques à partir des commentaires, puis récupérer ces utilisateurs, puis créer des modèles de vue à partir des (commentaires, utilisateurs) -paires. Facile avec LINQ/.NET, mais peut être difficile dans d'autres langues. Le nombre de requêtes est alors constant, correct. – mnemosyn

1

Ce que je ferais avec MongoDB serait d'intégrer l'ID utilisateur dans les commentaires (qui font partie de la structure du document « post »).

Trois conseils simples pour de meilleures performances:

1) Assurez-vous d'assurer un index sur la user_id

2) Utiliser la méthode de pagination commentaire pour éviter l'interrogation 200 fois la base de données

3) Mise en cache est votre ami

0

Vous pouvez mettre en cache vos objets utilisateur afin de ne pas avoir à interroger la base de données à chaque fois.

J'aime l'idée d'intégrer des données utilisateur dans chaque article, mais il faut alors penser à ce qui se passe lorsque le profil d'un utilisateur est mis à jour? doit s'assurer qu'aucun poste n'est manqué.

Je vous recommande de commencer par écrémer comment mongo vous recommande de gérer les schémas.

Généralement, pour les relations "contenant" entre entités, doit être choisi. Utiliser la liaison lorsque vous n'utilisez pas la liaison entraînerait une duplication des données.

http://www.mongodb.org/display/DOCS/Schema+Design

+1

, mais juste après avoir lu ce post officiel i décidé sur l'intégration. Et maintenant, quand le projet grandit, l'objet utilisateur se développe et déjà deux fois rencontré le problème, cet objet de commentaire manque un peu d'objet utilisateur (ne poussait pas toutes les données, seulement nécessaire). Eh bien, c'est devenu un tel gâchis. Bien sûr, je suis conscient de la mise en cache. Mais en pensant à la performance, je préfère obtenir le meilleur avant la mise en cache, et ne pas utiliser la mise en cache comme solution. – Tigra

Questions connexes