Reduzir $lookup
operações
Nesta página
Visão geral
As operações $lookup
ligam dados de duas collections no mesmo banco de dados baseado em um campo especificado. As operações $lookup
podem ser úteis quando seus dados são estruturados de forma semelhante a um banco de dados relacional e você precisa modelar grandes conjuntos de dados hierárquicos. No entanto, essas operações podem ser lentas e consomem muitos recursos porque precisam ler e executar lógica em duas collections em vez de em uma única.
Se você executar operações $lookup
com frequência, considere reestruturar seu esquema de forma que o aplicativo possa consultar uma única collection para obter todas as informações necessárias. Você pode usar o modelo de esquema flexível do MongoDB com documentos e arrays incorporados para capturar relacionamentos entre dados em uma única estrutura de documento. Use este modelo desnormalizado para aproveitar os documentos avançados do MongoDB e permitir que seu aplicativo recupere e manipule dados relacionados em uma única query.
Exemplos
Os exemplos a seguir mostram duas estruturas de esquema projetadas para reduzir operações $lookup
:
Usar documentos incorporados
Considere o exemplo a seguir, em que um mercado acompanha informações nutricionais e de estoque individual em duas collections separadas. Cada item do estoque corresponde a um item exclusivo de informações nutricionais. O campo nutrition_id
vincula a collection inventory
à collection nutrition_facts
, semelhante a um banco de dados tabular:
// inventory collection { "name": "Pear", "stock": 20, "nutrition_id": 123, // reference to a nutrition_fact document ... } { "name": "Candy Bar", "stock": 26, "nutrition_id": 456, ... }
// nutrition_facts collection { "_id": 123, "calories": 100, "grams_sugar": 17, "grams_protein": 1, ... } { "_id": 456, "calories": 250, "grams_sugar": 27, "grams_protein": 4, ... }
Se um aplicativo solicitar as informações nutricionais para um item de estoque pelo name
, esta estrutura de esquema exigirá um $lookup
da collection do nutrition_facts
para localizar uma entrada que corresponda ao nutrition_id
do item de estoque.
Em vez disso, você pode incorporar as informações nutricionais dentro da collection inventory
:
// inventory collection { "name": "Pear", "stock": 20, "nutrition_facts": { "calories": 100, "grams_sugar": 17, "grams_protein": 1, ... } ... } { "name": "Candy Bar", "stock": 26, "nutrition_facts": { "calories": 250, "grams_sugar": 27, "grams_protein": 4, ... } ... }
Dessa forma, quando você consulta um item em inventory
, as informações nutricionais são incluídas no resultado sem a necessidade de outra query ou de uma operação de $lookup
. Considere a possibilidade de incorporar documentos quando os dados das collections tiverem um relacionamento de um para um.
Usar arrays
Considere o exemplo a seguir em que documentos na collection players
de uma liga de beisebol fazem referência a documentos em uma collection teams
, semelhante a um banco de dados tabular:
// players collection { "team_id": 1, // reference to a team document "name": "Nick", "position": "Pitcher" ... } { "team_id": 1, "name": "Anuj", "position": "Shortstop" ... }
// teams collection { "_id": 1, "name": "Danbury Dolphins" ... }
Se um aplicativo solicitar uma lista de jogadores de um time, essa estrutura de esquema exigirá um $lookup
da collection players
para encontrar cada jogador que corresponda a um team_id
.
Em vez disso, você pode listar os players
em uma array no próprio documento da equipe:
// teams collection { "_id": 1, "name": "Danbury Dolphins", "players": [ { "name": "Nick", "position": "Pitcher" ... }, { "name": "Anuj", "position": "Shortstop" ... } ] }
Ao usar arrays para armazenar dados relacionados, um aplicativo pode recuperar informações team
completas, incluindo os jogadores do time, sem operações de $lookup
ou índices em outras collections. Nesse caso, usar arrays é mais eficiente do que armazenar as informações em collections separadas.
Observação
No exemplo acima, os times de beisebol têm um número definido de jogadores e não há risco de as arrays se tornarem excessivamente grandes.
Considerações sobre arrays
O custo de desempenho da leitura e gravação em arrays grandes pode superar o benefício obtido ao evitar as operações $lookup
. Se seus arrays forem ilimitados ou excessivamente grandes, eles podem prejudicar o desempenho de leitura e gravação.
Se você criar um índice em uma array, cada elemento na array será indexado. Se você escrever nessa array com frequência, o custo de desempenho de indexação ou reindexação de um campo da array potencialmente grande pode ser significativo.
Desnormalização
A desnormalização do esquema é o processo de duplicação de campos ou de derivação de novos campos a partir dos existentes. A desnormalização pode melhorar o desempenho de leitura em diversos casos, como:
Uma query recorrente exige alguns campos de um documento grande em outra collection. Você pode optar por manter uma cópia desses campos em um documento incorporado na collection que as queries recorrentes visam evitar a mesclagem de duas collections distintas ou a realização de operações frequentes de
$lookup
.Um valor médio de algum campo em uma collection é frequentemente solicitado. Você pode optar por criar um campo derivado em uma collection separada que é atualizada como parte de suas escritas e mantém uma média em execução para esse campo.
Embora a incorporação de documentos ou arrays sem duplicação seja preferida para agrupar dados relacionados, a desnormalização pode melhorar o desempenho de leitura quando for preciso manter collections separadas.
Observação
Quando você desnormaliza o esquema, é sua responsabilidade manter dados duplicados consistentes.
Saiba mais
A melhor estrutura para o esquema depende do contexto do aplicativo. Os recursos a seguir fornecem informações detalhadas sobre modelagem de dados e exemplos adicionais de casos de uso para documentos e arrays incorporados:
Modelos de dados
Para saber mais sobre modelagem de dados no MongoDB e o modelo de esquema flexível, consulte Introdução à modelagem de dados.
Para saber mais sobre as trocas entre modelos de dados incorporados e normalizados, consulte Design de modelo de dados.
O MongoDB também oferece um curso gratuito da Universidade MongoDB sobre Modelagem de Dados: Modelagem de Dados para o MongoDB.
Apresentações de modelagem de dados do MongoDB.live 2020
Para saber como incorporar o modelo de dados flexível em seu esquema, consulte as seguintes apresentações em MongoDB.live 2020:
Saiba mais sobre relacionamentos de entidade no MongoDB e exemplos de suas implementações com modelagem de dados com MongoDB.
Aprenda padrões avançados de design de modelagem de dados que você pode incorporar ao seu esquema com os Padrões Avançados de Design de Esquema.
arrays
Para saber mais sobre como consultar arrays no MongoDB, leia Consultar uma array.
Padrões de design
Para ler sobre situações em que as arrays funcionam bem, consulte os seguintes padrões de design:
Use o Padrão de Atributo para manipular dados com combinações exclusivas de atributos, como dados de filmes em que cada filme é lançado em um subconjunto de países.
Use o Padrão Bucket para lidar com dados sequenciais ou bem agrupados, como dados de intervalo de tempo.
Use o Padrão Polimórfico para lidar com documentos de formatos diferentes na mesma coleção, como registros de atletas de vários esportes.
Esquemas desnormalizados
Para ler sobre uma situação em que duplicar dados melhora o esquema, consulte o seguinte padrão de design:
Use o Padrão Extended Reference para duplicar uma porção de leitura frequente de dados de documentos grandes para documentos menores.