Pergunta

Quais são as melhores práticas para armazenar conjuntos aninhados (como árvores de comentários) em MongoDB?

Quero dizer, todos os comentários podem ter um comentário dos pais e comissões de filhos (respostas).

Armazenando -os assim:

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

Não é legal, porque não podemos, por exemplo, pedir "todos os post que são comentados por Peter" sem mapa/redução.

Foi útil?

Solução

Eu acho que não há solução perfeita - depende de quais operações são mais importantes para o seu aplicativo. Acredito que o Silicon Alley Insider armazena comentários aninhados com MongoDB, por exemplo. Isso torna a consulta que você menciona mais.

Uma opção é armazenar no nível superior na postagem de uma lista de todos os comentaristas em uma matriz. Pense nisso como dados desnormalizados. Então, pode -se encontrar facilmente todas as postagens que envolvem um determinado comentarista. Em seguida, para perfurar, você usa mapa/redução ou db.eval () para obter as informações postais aninhadas dentro.

Outra nota - se você estiver lidando com um único documento, o db.eval () provavelmente é mais leve que o mapa/redução. $ onde também é uma opção, mas pode ser lento, por isso gosto da 'lista de comentaristas' mencionada acima - não é fácil indexar essa matriz também (consulte 'Multikey' nos documentos).

Veja também:http://groups.google.com/group/mongodb-user/browse_thread/thread/df8250573c91f75a/e880d9c57e343b52?lnk=gst&q=treees#e880d9c57e343b52

Outras dicas

No link do post de DM, Dwight Merriman menciona usando uma chave de caminho e fazendo correspondências de regex

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

Outra maneira de fazer isso seria com as matrizes

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

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

Isso deve torná -lo muito rápido.

Se cada nó só puder estar em um único caminho, você não precisará se preocupar com onde está localizado na lista

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

encontraria todos os filhos de "A"

Em vez de nomes de caminhos, eu provavelmente usaria a _id dos nós.

Atualizar

  • Uma coisa a ter cuidado é que um índice só pode ter uma matriz.
  • Tenha cuidado para usar explicar em suas consultas

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

da-te

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

mas

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

usa apenas o primeiro elemento e depois digitaliza todos os resultados correspondentes para b.
Se A é o seu elemento raiz ou estiver na maioria dos seus registros, você está fazendo uma varredura quase completa dos registros, em vez de uma consulta de índice eficiente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top