Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ / /

Agrupar dados com padrão de Bucket

Nesta página

  • Sobre esta tarefa
  • Passos
  • Agrupar os dados por customerId
  • Adicione um identificador e conte para cada bucket
  • Próximos passos
  • Consultar dados com o padrão de bucket
  • Inserir dados com o padrão Bucket
  • Resultados
  • Saiba mais

O padrão de bucket separa longas séries de dados em objetos distintos. Separar grandes séries de dados em grupos menores pode melhorar os padrões de acesso à consulta e simplificar a lógica do aplicativo. O bucketing é útil quando você tem objetos semelhantes relacionados a uma entidade central, como negociações de ações feitas por um único usuário.

Você pode utilizar o padrão bucket para paginação, agrupando seus dados com base nos elementos que seu aplicativo mostra por página. Essa abordagem utiliza o modelo de dados flexível do MongoDB para armazenar dados de acordo com os dados que seus aplicativos precisam.

Dica

As coleções de séries temporais aplicam o padrão de bucket automaticamente e são adequadas para a maioria das aplicações que envolvem o agrupamento de dados de séries temporais.

Considere o esquema a seguir que acompanha as negociações de ações. O esquema inicial não utiliza o padrão de bucket e armazena cada negociação em um documento individual.

db.trades.insertMany(
[
{
"ticker" : "MDB",
"customerId": 123,
"type" : "buy",
"quantity" : 419,
"date" : ISODate("2023-10-26T15:47:03.434Z")
},
{
"ticker" : "MDB",
"customerId": 123,
"type" : "sell",
"quantity" : 29,
"date" : ISODate("2023-10-30T09:32:57.765Z")
},
{
"ticker" : "GOOG",
"customerId": 456,
"type" : "buy",
"quantity" : 50,
"date" : ISODate("2023-10-31T11:16:02.120Z")
}
]
)

O aplicativo mostra transações de ações feitas por um único cliente de cada vez e mostra 10 transações por página. Para simplificar a lógica do aplicativo, use o padrão bucket para agrupar as transações por customerId em grupos de 10.

1

Reorganizar o esquema para ter um único documento para cada customerId:

{
"customerId": 123,
"history": [
{
"type": "buy",
"ticker": "MDB",
"qty": 419,
"date": ISODate("2023-10-26T15:47:03.434Z")
},
{
"type": "sell",
"ticker": "MDB",
"qty": 29,
"date": ISODate("2023-10-30T09:32:57.765Z")
}
]
},
{
"customerId": 456,
"history": [
{
"type" : "buy",
"ticker" : "GOOG",
"quantity" : 50,
"date" : ISODate("2023-10-31T11:16:02.120Z")
}
]
}

Com o padrão de bucket:

  • Os documentos com valores customerId comuns são condensados em um único documento, no qual customerId é um campo de nível superior.

  • As negociações desse cliente são agrupadas em um campo de array incorporado, chamado history.

2
1db.trades.drop()
2
3db.trades.insertMany(
4 [
5 {
6 "_id": "123_1698349623",
7 "customerId": 123,
8 "count": 2,
9 "history": [
10 {
11 "type": "buy",
12 "ticker": "MDB",
13 "qty": 419,
14 "date": ISODate("2023-10-26T15:47:03.434Z")
15 },
16 {
17 "type": "sell",
18 "ticker": "MDB",
19 "qty": 29,
20 "date": ISODate("2023-10-30T09:32:57.765Z")
21 }
22 ]
23 },
24 {
25 "_id": "456_1698765362",
26 "customerId": 456,
27 "count": 1,
28 "history": [
29 {
30 "type" : "buy",
31 "ticker" : "GOOG",
32 "quantity" : 50,
33 "date" : ISODate("2023-10-31T11:16:02.120Z")
34 }
35 ]
36 },
37 ]
38)

O valor do campo _id é uma concatenação de customerId mais o tempo da primeira negociação em segundos (a partir da era UNIX) no campo history .

O campo count indica quantos elementos estão na array history desse documento. O campo count é usado para implementar a lógica de paginação.

Depois de atualizar o esquema para usar o padrão de bucket, atualize a lógica do aplicativo para ler e gravar dados. Consulte as seções a seguir:

  • Consultar dados com o padrão de bucket

  • Inserir dados com o padrão Bucket

No esquema atualizado, cada documento contém dados para uma única página no aplicativo. Você pode usar os campos _id e count para determinar como retornar e atualizar dados.

Para consultar dados na página apropriada, use uma query regex para obter dados de um customerId especificado e use skip para retornar aos dados da página correta. A query regex em _id usa índice _id padrão, o que resulta em consultas de alto desempenho sem a necessidade de um índice adicional.

A consulta a seguir retorna dados da primeira página de negociações para o cliente 123:

db.trades.find( { "_id": /^123_/ } ).sort( { _id: 1 } ).limit(1)

Para retornar dados para páginas posteriores, especifique um valor de skip menor do que a página para a qual você deseja mostrar dados. Por exemplo, para mostrar dados para a página 10, execute a seguinte query:

db.trades.find( { "_id": /^123_/ } ).sort( { _id: 1 } ).skip(9).limit(1)

Observação

A query anterior não retorna resultados porque os dados de amostra contêm apenas documentos da primeira página.

Agora que o esquema usa o padrão de bucket, atualize a lógica do aplicativo para inserir novas negociações no bucket correto. Use o comando update para inserir a negociação no bucket com o customerId e o bucket apropriados.

O comando a seguir insere uma nova negociação para customerId: 123:

db.trades.updateOne( { "_id": /^123_/, "count": { $lt: 10 } },
{
"$push": {
"history": {
"type": "buy",
"ticker": "MSFT",
"qty": 42,
"date": ISODate("2023-11-02T11:43:10")
}
},
"$inc": { "count": 1 },
"$setOnInsert": { "_id": "123_1698939791", "customerId": 123 }
},
{ upsert: true }
)

O aplicação exibe 10 transações por página. O filtro de atualização procura um documento para customerId: 123 onde o count é menor que 10, o que significa que o bucket não contém uma página inteira de dados.

  • Se houver um documento que corresponda a "_id": /^123_/ e seu count for menor que 10, o comando de atualização empurrará a nova transação para a array history do documento correspondente.

  • Se não houver um documento correspondente, o comando de atualização inserirá um novo documento com a nova transação (porque upsert é true). O campo _id do novo documento é uma concatenação do customerId e o tempo em segundos desde a Era UNIX da transação.

A lógica para comandos de atualização evita arrays ilimitadas, garantindo que nenhuma array history contenha mais de 10 documentos.

Depois de executar a operação de atualização, a coleção trades tem os seguintes documentos:

[
{
_id: '123_1698349623',
customerId: 123,
count: 3,
history: [
{
type: 'buy',
ticker: 'MDB',
qty: 419,
date: ISODate("2023-10-26T15:47:03.434Z")
},
{
type: 'sell',
ticker: 'MDB',
qty: 29,
date: ISODate("2023-10-30T09:32:57.765Z")
},
{
type: 'buy',
ticker: 'MSFT',
qty: 42,
date: ISODate("2023-11-02T11:43:10.000Z")
}
]
},
{
_id: '456_1698765362',
customerId: 456,
count: 1,
history: [
{
type: 'buy',
ticker: 'GOOG',
quantity: 50,
date: ISODate("2023-10-31T11:16:02.120Z")
}
]
}
]

Depois de implementar o padrão de bucket, você não precisa incorporar a lógica de paginação para retornar resultados em seu aplicação. A forma como os dados são armazenados corresponde à forma como são utilizados no aplicação.

Voltar

Dados do grupo