Domanda

Quali sono le migliori pratiche per memorizzare nested set (come alberi di commenti) in MongoDB?

Voglio dire, ogni commento può avere un genitore commento e bambini-commenti (risposte).

La loro memorizzazione come questo:

{
   title: "Hello",
   body: "Please comment me!",
   comments: [
        {
            author: "Peter",
            text: "Hi there",
            answers: [
                  {
                      author: "Peter",
                      text: "Hi there",
                      answers: [
                                 { author: "Ivan", text: "Hi there" },
                                 { author: "Nicholas", text: "Hi there" }
                      ]
                  },
                  { author: "Ivan", text: "Hi there" },
                  { author: "Nicholas", text: "Hi there" },
            ]
        },
        { author: "Ivan", text: "Hi there" },
        { author: "Nicholas", text: "Hi there" },
   ]
}

non è cool, perché noi non possiamo, per esempio, per chiedere "tutti i post che sono commentati da Pietro" senza mappa/ridurre.

È stato utile?

Soluzione

Credo che non esiste una soluzione perfetta - dipende da ciò che le operazioni sono più importanti per la vostra applicazione. Credo che memorizza Silicon Alley Insider commenti nidificati con MongoDB per esempio. Che fa rendere la query si parla di più.

Una possibilità è conservare a livello superiore nel post un elenco di tutti i commentatori in un array. Pensare che i dati denormalizzati. Poi si può trovare facilmente tutti i messaggi che implicano un certo commentatore. Poi di drill-down, è possibile utilizzare la mappa / ridurre o db.eval () per ottenere informazioni posta nidificato all'interno.

Un'altra nota - se si tratta di un unico documento, db.eval () è probabilmente più leggero rispetto mappa / ridurre. $ Dove è anche una possibilità, ma può essere lento quindi mi piace l'ulteriore 'elenco dei commentatori' di cui sopra -. Non è facile anche per indicizzare anche che array (vedi 'Multitasto' nella documentazione)

Si veda anche: http: // gruppi. google.com/group/mongodb-user/browse_thread/thread/df8250573c91f75a/e880d9c57e343b52?lnk=gst&q=trees#e880d9c57e343b52

Altri suggerimenti

Nel collegamento dal dm post di Dwight Merriman accenna all'uso di una chiave del percorso e facendo regex

{
  path : "a.b.c.d.e.f"
}

Un altro modo per farlo sarebbe con le matrici

{
  path : ["a", "b", "c", "d", "e", "f"]
}

db.test.ensureIndex({path: 1})

che dovrebbe rendere abbastanza veloce.

se ogni nodo può essere solo in un unico percorso, quindi non avrebbe bisogno di non preoccuparsi di dove è situato nella lista

db.test.find({path: "a"})

vorresti trovare tutti figli di "a"

Invece di nomi di percorso, avrei probabilmente usare il _id dei nodi.

Aggiornamento

  • una cosa da stare attenti è che un indice può avere solo un array in esso.
  • Prestare attenzione a utilizzare spiegare sulla query

    db.test.find({path:{$a:["a", "b"]})

ti dà

 db.test.find({path: {$in: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1 multi",
        "nscanned" : 2,
        "nscannedObjects" : 2,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ],
                        [
                                "b",
                                "b"
                        ]
                ]
        }
}

ma

 db.test.find({path: {$all: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1",
        "nscanned" : 1,
        "nscannedObjects" : 1,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ]
                ]
        }
}

utilizza solo il primo elemento e quindi effettua la scansione di tutti i corrispondenti risultati per b.
Se a è un elemento radice o è nella maggior parte dei record poi fa quasi una scansione completa del record invece di un efficace indice di query.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top