MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

progettazione dello schema mongodb per i blog

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] },
    ...
  ]
}

La premessa di base qui è che ho annidato i Comments all'interno dell'Article . I Votes applicare solo a un Comment , quindi sono stati archiviati come un array con ogni Comment . In questo caso, ho appena memorizzato user_id. Se vuoi memorizzare più informazioni (time_created, ecc.), puoi votare una serie di oggetti:

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

Come eseguire le tue query in modo efficiente:

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

Questo ottiene tutto con una query. Potrebbe essere necessario eseguire una logica lato client per contare i voti per commento, ma questo è piuttosto banale.

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

L'indice consentirà di cercare in modo efficiente i commenti all'interno di un documento.

Al momento non è possibile estrarre solo le corrispondenze da un sottoarray. Questa query restituirà infatti tutti gli articoli con commenti di quell'utente. Se si tratta potenzialmente di troppi dati, puoi eseguire un po' di ritaglio.

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 } )

Anche in questo caso, verranno restituiti tutti gli articoli, non solo i commenti.

C'è un compromesso da fare qui. La restituzione dell'articolo potrebbe sembrare che stiamo riportando troppi dati. Ma cosa intendi mostrare all'utente quando esegui la query n. 3?

Ottenere un elenco di "commenti per cui ho votato" non è molto utile senza il commento stesso. Ovviamente il commento non è molto utile senza l'articolo stesso (o almeno solo il titolo).

La maggior parte delle volte, la query n. 3 si trasforma in un join da Votes a Comments agli Articles . Se è così, perché non riportare semplicemente gli articoli per cominciare?