Documentos volumosos
Armazenar campos de dados relacionados entre si, mas não acessados juntos, pode criar documentos inchados que levam ao uso excessivo de RAM e largura de banda. Oconjunto de trabalho , que consiste em dados e índices acessados com frequência, é armazenado na alocação de RAM. Quando o conjunto de trabalho cabe na RAM, o MongoDB pode consultar da memória em vez do disco, o que melhora o desempenho. No entanto, se os documentos forem muito grandes, o conjunto de trabalho pode não caber na RAM, fazendo com que o desempenho se degrade, pois o MongoDB precisa acessar dados do disco.
Para evitar documentos inchados, reestruture seu esquema com documentos menores e use referências de documento para separar campos que não são retornados juntos. Essa abordagem reduz o tamanho do conjunto de trabalho e melhora o desempenho.
Sobre esta tarefa
Considere o seguinte esquema que contém informações de livros usadas na página principal de um website de livreira. A página principal exibe apenas o título do livro, o autor e a imagem da capa. Clique no livro para ver mais detalhes.
{ title: "Tale of Two Cities", author: "Charles Dickens", genre: "Historical Fiction", cover_image: "<url>", year: 1859, pages: 448, price: 15.99, description: "A historical novel set during the French Revolution. }
No esquema atual, para exibir as informações da página principal do site, todas as informações do livro devem ser consultadas. Para reduzir o tamanho do documento e simplificar as queries, você pode divisão o documento grande em duas coleções menores.
Exemplo
No exemplo a seguir, as informações do livro são divisão em duas collections: mainBookInfo
e additionalBookDetails
.
A coleção
mainBookInfo
contém as informações exibidas na página principal do website.A coleção
additionalBookDetails
contém detalhes extras revelados depois que o usuário clica no livro.
A collection mainBookInfo
:
db.mainBookInfo.insertOne( { _id: 1234, title: "Tale of Two Cities", author: "Charles Dickens", genre: "Historical Fiction", cover_image: "<url>" } )
A collection additionalBookDetails
:
db.additionalBookDetails.insertOne( { title: "Tale of Two Cities", bookId: 1234, year: 1859, pages: 448, price: 15.99, description: "A historical novel set during the French Revolution." } )
As duas collections são vinculadas pelo campo _id
na collection mainBookInfo
e pelo campo bookId
na collection additionalBookDetails
. Na página inicial, somente a coleção mainBookInfo
é usada para fornecer as informações necessárias. Quando um usuário seleciona um livro para saber mais sobre, o site faz query da collection additionalBookDetails
usando o campo _id
para corresponder ao campo bookId
.
Ao dividir as informações em duas coleções, você garante que seus documentos não fiquem muito grandes e excedam a alocação de RAM.
Junte-se a coleções com $lookup
Para unir os dados da collection mainBookInfo
e da collection additionalBookDetails
, o aplicação precisa executar uma operação $lookup
.
A seguinte operação de agregação une a coleção mainBookInfo
e additionalBookDetails
do exemplo anterior.
db.mainBookInfo.aggregate( [ { $lookup: { from: "additionalBookDetails", localField: "_id", foreignField: "bookId", as: "details" } }, { $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$details", 0 ] }, "$$ROOT" ] } } }, { $project: { details: 0 } } ] )
A operação retorna o seguinte:
[ { _id: ObjectId('666b1235eda086b5e22dbcf1'), title: 'Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical Fiction', cover_image: '<url>', bookId: 1234, year: 1859, pages: 448, price: 15.99, description: 'A historical novel set during the French Revolution.' } ]
Neste exemplo, a operação $lookup
une a collection mainBookInfo
com a collection additionalBookDetails
utilizando os campos _id
e bookId
. As operações $mergeObjects
e $replaceRoot
mesclam os documentos unidos das collections mainBookInfo
e additionalBookDetails
.