MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

conception de schéma mongodb pour les blogs

Article {
  "_id" : "A",
  "title" : "Hello World",
  "user_id" : 12345,
  "text" : 'My test article',

  "comments" : [
    { 'text' : 'blah', 'user_id' : 654321, 'votes' : [987654]},
    { 'text' : 'foo', 'user_id' : 987654, 'votes' : [12345, 654321] },
    ...
  ]
}

Le principe de base ici est que j'ai imbriqué les Comments à l'intérieur de l'Article . Les Votes ne s'applique qu'à un Comment , ils ont donc été stockés sous forme de tableau avec chaque Comment . Dans ce cas, je viens de stocker le user_id. Si vous souhaitez stocker plus d'informations (time_created, etc.), vous pouvez voter sur un tableau d'objets :

... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...

Comment effectuer vos requêtes efficacement :

db.articles.find( { _id : 'A' } )

Cela obtient tout avec une seule requête. Vous devrez peut-être appliquer une certaine logique côté client pour compter les votes par commentaire, mais c'est assez trivial.

db.articles.ensureIndex( { "comments.user_id" : 1 } )
db.articles.find( { "comments.user_id" : 987654 } ) // returns all document fields

L'index permettra de rechercher efficacement les commentaires dans un document.

Il n'existe actuellement aucun moyen d'extraire uniquement les correspondances d'un sous-tableau. Cette requête renverra en fait tous les articles avec des commentaires de cet utilisateur. Si c'est potentiellement beaucoup trop de données, vous pouvez faire quelques ajustements.

db.articles.find( { "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
db.articles.ensureIndex( { "comments.votes" : 1 } )
db.articles.find( { "comments.votes" : 987654 } )

Encore une fois, cela renverra tous les articles, pas seulement les commentaires.

Il y a un compromis à faire ici. Rendre l'article peut donner l'impression que nous ramenons trop de données. Mais qu'envisagez-vous d'afficher à l'utilisateur lorsque vous effectuez la requête #3 ?

Obtenir une liste de "commentaires pour lesquels j'ai voté" n'est pas très utile sans le commentaire lui-même. Bien sûr, le commentaire n'est pas très utile sans l'article lui-même (ou du moins juste le titre).

La plupart du temps, la requête #3 se transforme en une jointure à partir de Votes vers Comments vers Articles . Si tel est le cas, pourquoi ne pas simplement ramener les articles pour commencer ?