Agrupar dados com o padrão de atributo
O padrão de atributo é um padrão de design de esquema que ajuda a organizar documentos com muitos campos semelhantes, especialmente quando os campos compartilham características comuns. Se você precisar classificar ou consultar esses subconjuntos de campos semelhantes, o padrão de atributo poderá otimizar seu esquema. Ele cria uma indexação de documento mais fácil, consolidando vários campos semelhantes por documento em um subdocumento de valor-chave. Ao invés de criar múltiplos índices em vários campos semelhantes, o padrão de atributo permite criar menos índices, tornando suas queries mais rápidas e simples de escrever.
Use o padrão de atributo se alguma das seguintes condições se aplicar à sua collection:
Você tem documentos grandes contendo muitos campos semelhantes com características compartilhadas que você deseja classificar ou consultar.
Um pequeno subconjunto de documentos contém os campos necessários para classificação.
Sobre esta tarefa
Considere uma coleção de filmes. Documentos típicos na coleção podem ter a seguinte aparência:
db.movies.insertOne( { "_id": 1, "title": "Star Wars", "runtime": 121, "directors": ["George Lucas"], release_US: ISODate("1977-05-20T01:00:00+01:00"), release_France: ISODate("1977-10-19T01:00:00+01:00"), release_Italy: ISODate("1977-10-20T01:00:00+01:00"), release_UK: ISODate("1977-12-27T01:00:00+01:00") } )
Observe os vários campos de data de lançamento para diferentes países no documento acima . Se você quiser procurar uma data de lançamento, deverá procurar em muitos campos ao mesmo tempo. Sem o padrão de atributo, você precisaria criar vários índices na coleção movies
para executar rapidamente pesquisas sobre datas de lançamento:
db.movies.createIndex({ release_US: 1 }); db.movies.createIndex({ release_France: 1 }); db.movies.createIndex({ release_Italy: 1 }); db.movies.createIndex({ release_UK: 1 });
No entanto, os índices são caros e podem diminuir o desempenho, especialmente para operações de gravação. O procedimento a seguir demonstra como você pode aplicar o padrão de atributo à collection movies
movendo o subconjunto de informações de diferentes datas de lançamento em uma array, reduzindo as necessidades de indexação.
Passos
Agrupe subconjuntos de dados em um array.
Reorganizar o esquema para transformar os vários campos de data de lançamento em uma array de pares de valores-chave:
db.movies.insertOne( { "_id": 1, "title": "Star Wars", "runtime": 121, "directors": ["George Lucas"], releases: [ { location: "USA", date: ISODate("1977-05-20T01:00:00+01:00") }, { location: "France", date: ISODate("1977-10-19T01:00:00+01:00") }, { location: "Italy", date: ISODate("1977-10-20T01:00:00+01:00") }, { location: "UK", date: ISODate("1977-12-27T01:00:00+01:00") } ] } )
Resultados
Se um documento tiver vários campos que rastreiam as mesmas características ou semelhantes, o padrão de atributo evita a necessidade de criar índices em cada campo semelhante. Ao consolidar campos semelhantes em uma array e criar um índice nessa array, você reduz o número total de índices necessários e melhora o desempenho da query.
Outros casos de uso
O padrão de atributo pode ser útil quando seu documento descreve as características dos itens. Alguns produtos, como roupas, podem ter tamanhos expressos em pequeno, médio ou grande. Outros produtos na mesma coleção podem ser expressos em volume, enquanto outros podem ser expressos em dimensões físicas ou peso.
Por exemplo, considere uma coleção de Garrafas de Águla . Um documento que não usa o padrão de atributo pode ter a seguinte aparência:
db.bottles.insertOne([ { "_id": 1, "volume_ml": 500, "volume_ounces": 12 } ])
O seguinte código aplica o padrão de atributo à coleção bottles
:
db.bottles.insertOne([ { "_id": 1, specs: [ { k: "volume", v: "500", u: "ml" }, { k: "volume", v: "12", u: "ounces" }, ] } ])
Como os campos volume_ml
e volume_ounces
no primeiro documento contêm informações semelhantes, o esquema acima os consolida em um campo, specs
. O campo specs
agrupa informações sobre as especificações de medição de uma determinada Garrafa de Águla, onde o campo k
especifica o que está sendo medido, v
especifica o valor e u
especifica a unidade de medida.
O padrão de atributo também permite agrupar campos semelhantes com nomes diferentes. Ao especificar atributos por meio de pares de valores-chave, como o campo k
, que especifica o que está sendo medido, você pode armazenar uma variedade mais ampla de campos semelhantes em uma array, minimizando o número de índices necessários para consultar seus dados com eficiência.
Por exemplo, considere este documento na collection bottles
que não usa o padrão de atributo. Este documento armazena especificações sobre o volume e a altura da Garrafa de Águla:
db.bottles.insertOne([ { "_id": 1, "volume_ml": 500, "volume_ounces": 12, "height_inches": 8 } ])
O código a seguir aplica o padrão de atributo ao documento. Ele agrupa os campos volume_ml
, volume_ounces
e height_inches
todos na array specs
:
db.bottles.insertOne([ { "_id": 1, specs: [ { k: "volume", v: "500", u: "ml" }, { k: "volume", v: "12", u: "ounces" }, { k: "height", v: "8", u: "inches" } ] } ])
O uso de pares de valores-chave, como k
, v
e u
, permite mais flexibilidade em quais campos você pode adicionar à array. Quanto mais campos você puder consolidar na array, menos índices precisará criar, maximizando o desempenho da query.