Menu Docs

Página inicial do DocsIniciar e gerenciar o MongoDBMongoDB Atlas

Reduza $lookup as operações

Nesta página

  • Visão geral
  • Exemplos
  • Desnormalização
  • Saiba mais

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 seu 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.

Os exemplos a seguir mostram duas estruturas de esquema projetadas para reduzir operações $lookup :

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.

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.

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.

Dica

Veja também:

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.

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:

Para saber como incorporar o modelo de dados flexível em seu esquema, consulte as seguintes apresentações em MongoDB.live 2020:

Para saber mais sobre como consultar arrays no MongoDB, leia Consultar uma array.

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 collection, como registros de atletas de vários esportes.

Para ler sobre uma situação em que duplicar dados melhora o esquema, consulte o seguinte padrão de design:

← Melhore seu esquema