Menu Docs

Agregação com dados de preferência do usuário

Considere um banco de banco de dados de clube esportivo com uma coleção members que rastreia os nomes dos membros, as datas de adesão e as preferências esportivas:

db.members.insertMany( [
{
_id: "jane",
joined: ISODate("2011-03-02"),
likes: ["golf", "racquetball"]
},
{
_id: "joe",
joined: ISODate("2012-07-02"),
likes: ["tennis", "golf", "swimming"]
},
{
_id: "ruth",
joined: ISODate("2012-01-14"),
likes: ["golf", "racquetball"]
},
{
_id: "harold",
joined: ISODate("2012-01-21"),
likes: ["handball", "golf", "racquetball"]
},
{
_id: "kate",
joined: ISODate("2012-01-14"),
likes: ["swimming", "tennis"]
}
] )

A operação a seguir usa $project para retornar somente o campo _id para todos os documentos na coleção members :

db.members.aggregate(
[
{ $project: { _id: 1 } }
]
)

A operação retorna os seguintes documentos:

[
{ _id: 'jane' },
{ _id: 'joe' },
{ _id: 'ruth' },
{ _id: 'harold' },
{ _id: 'kate' }
]

Para operações básicas de query e projeção , as queries padrão com o método find() têm o melhor desempenho.

A seguinte operação gera os nomes dos membros em letras maiúsculas e em ordem alfabética. Faça isso para normalizar os nomes dos membros para seu processamento.

db.members.aggregate(
[
{ $project: { name: { $toUpper: "$_id" }, _id: 0 } },
{ $sort: { name: 1 } }
]
)

Todos os documentos da coleção members passam pelo pipeline, que consiste nas seguintes operações:

  • O operador $project:

    • cria um novo campo chamado name.

    • converte o valor do _id para letra maiúscula, com o operador $toUpper. Então o $project cria um novo campo, denominado name para manter este valor.

    • suprime o campo id. $project passará o campo _id por padrão, a menos que explicitamente suprimido.

  • O operador $sort solicita os resultados pelo campo name.

A operação retorna o seguinte resultado:

[
{ name: 'HAROLD' },
{ name: 'JANE' },
{ name: 'JOE' },
{ name: 'KATE' },
{ name: 'RUTH' }
]

A seguinte operação de agregação gera os nomes dos nós ordenados pelo mês de adesão. Você pode usar esta agregação para ajudar a gerar avisos de renovação de adesão.

db.members.aggregate( [
{
$project: {
month_joined: { $month: "$joined" },
name: "$_id",
_id: 0
}
},
{ $sort: { month_joined: 1 } }
] )

O pipeline passa todos os documentos na coleção members através das seguintes operações:

  • O operador $project:

    • Cria dois novos campos: month_joined e name.

    • Suprime o id dos resultados. O método aggregate() inclui o _id, a menos que explicitamente suprimido.

  • O operador $month converte os valores do campo joined para representações inteiras do mês. Em seguida, o operador $project atribui esses valores ao campo month_joined.

  • O operador $sort classifica os resultados pelo campo month_joined.

A operação retorna o seguinte resultado:

[
{ month_joined: 1, name: 'ruth' },
{ month_joined: 1, name: 'harold' },
{ month_joined: 1, name: 'kate' },
{ month_joined: 3, name: 'jane' },
{ month_joined: 7, name: 'joe' }
]

A operação abaixo mostra quantas pessoas aderiram em cada mês do ano. Use estes dados agregados para estratégias de recrutamento e marketing.

db.members.aggregate( [
{ $project: { month_joined: { $month: "$joined" } } } ,
{ $group: { _id: { month_joined: "$month_joined" } , number: { $sum: 1 } } },
{ $sort: { "_id.month_joined": 1 } }
] )

O pipeline passa todos os documentos na coleção members através das seguintes operações:

  • O operador $project cria um novo campo denominado month_joined.

  • O operador $month converte os valores do campo joined para representações inteiras do mês. Em seguida, o operador $project atribui os valores ao campo month_joined.

  • O operador $group coleta todos os documentos com um determinado valor month_joined e conta quantos documentos existem para esse valor. Especificamente, para cada valor único, $group cria um novo documento "por mês" com dois campos:

    • _id, que contém um documento aninhado com o campo month_joined e seu valor.

    • number, que é um campo gerado. O operador $sum incrementa este campo por 1 para cada documento contendo o valor de month_joined fornecido.

  • O operador $sort classifica os documentos criados por $group de acordo com o conteúdo do campo month_joined.

A operação de agregação retorna os seguintes documentos:

[
{ _id: { month_joined: 1 }, number: 3 },
{ _id: { month_joined: 3 }, number: 1 },
{ _id: { month_joined: 7 }, number: 1 }
]

A agregação a seguir coleta as cinco atividades mais “curtidas” no conjunto de dados. Este tipo de análise pode ajudar a informar o planeamento e o desenvolvimento futuro.

db.members.aggregate(
[
{ $unwind: "$likes" },
{ $group: { _id: "$likes" , number: { $sum: 1 } } },
{ $sort: { number: -1 } },
{ $limit: 5 }
]
)

O pipeline começa com todos os documentos na coleção members e passa esses documentos pelas seguintes operações:

  • O operador $unwind separa cada valor na array likes e cria uma nova versão do documento de origem para cada elemento na array.

    Exemplo

    Dados os seguintes documentos na collection members:

    {
    _id: "jane",
    joined: ISODate("2011-03-02"),
    likes: ["golf", "racquetball"]
    }

    O operador $unwind gera os seguintes documentos:

    {
    _id: "jane",
    joined: ISODate("2011-03-02"),
    likes: "golf"
    }
    {
    _id: "jane",
    joined: ISODate("2011-03-02"),
    likes: "racquetball"
    }
  • O operador $group coleta todos os documentos com o mesmo valor para o campo likes e conta cada agrupamento. Com estas informações, o $group cria um novo documento com dois campos:

    • _id, que contém o valor likes.

    • number, que é um campo gerado. O operador $sum incrementa este campo por 1 para cada documento contendo o valor de likes fornecido.

  • O operador $sort classifica estes documentos pelo campo number em ordem reversa.

  • O operador $limit inclui apenas os primeiros 5 documentos de resultado.

A operação de agregação retorna os seguintes documentos:

[
{ _id: 'golf', number: 4 },
{ _id: 'racquetball', number: 3 },
{ _id: 'tennis', number: 2 },
{ _id: 'swimming', number: 2 },
{ _id: 'handball', number: 1 }
]