Question

les meilleures pratiques Que faites pour stocker des ensembles imbriqués (comme les arbres des commentaires) dans MongoDB?

Je veux dire, chaque commentaire peut avoir un commentaire de parent et les enfants commentaires (réponses).

Le stockage comme ceci:

{
   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" },
   ]
}

est pas cool, parce que nous ne pouvons pas, par exemple, demander "tous les post qui sont commentées par Peter" sans map / reduce.

Était-ce utile?

La solution

Je pense qu'il n'y a pas de solution parfaite - dépend de ce que les opérations sont plus importantes pour votre application. Je crois que la Silicon Alley Insider magasins commentaires imbriqués avec MongoDB par exemple. Cela ne rend la requête que vous mentionnez plus difficile.

L'une des options est au magasin de haut niveau dans le poste une liste de tous les intervenants dans un tableau. Pensez que les données dénormalisées. Ensuite, on peut facilement trouver tous les messages qui impliquent un certain commentateur. Puis forer vers le bas, vous utilisez la carte / ou réduire db.eval () pour obtenir les informations après imbriqué au sein.

Une autre note - si vous avez affaire à un seul document, db.eval () est probablement plus léger que map / reduce. $ Où est également une option, mais peut être lent, donc j'aime la « liste des commentateurs » additionnel mentionné ci-dessus -. Non, il est également facile d'indexer ce tableau trop (voir « Multitouche » dans les docs)

Voir aussi: http: // groupes. google.com/group/mongodb-user/browse_thread/thread/df8250573c91f75a/e880d9c57e343b52?lnk=gst&q=trees#e880d9c57e343b52

Autres conseils

Dans le lien de poste de dm Dwight Merriman en utilisant une clé mentions de chemin et de faire les matchs regex

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

Une autre façon de le faire serait avec des tableaux

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

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

qui devrait le rendre assez rapide.

si chaque noeud ne peut être dans un seul chemin alors vous ne devez pas inquiéter de savoir où il se trouve dans la liste

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

trouverait tous les enfants de "a"

Au lieu de noms de chemin, je serais probablement utiliser le _id des noeuds.

Mise à jour

  • une chose à faire attention est qu'un index ne peut avoir qu'un seul tableau en elle.
  • Veillez à utiliser expliquer vos requêtes

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

vous donne

 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"
                        ]
                ]
        }
}

 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"
                        ]
                ]
        }
}

utilise uniquement le premier élément, puis analyse tous les résultats correspondant à b pour.
Si un est votre élément racine ou est dans la plupart de vos dossiers alors que vous faites une analyse presque complète des enregistrements au lieu d'une requête d'index efficace.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top