$percentile (agregação)
Definição
$percentile
Novidades na versão 7.0.
Retorna uma array de valores escalares que correspondem aos valorespercentuais especificados.
Você pode utilizar o
$percentile
como um acumulador na etapa$group
ou como uma expressão de escalonamento.
Sintaxe
A sintaxe para $percentile
é:
{ $percentile: { input: <expression>, p: [ <expression1>, <expression2>, ... ], method: <string> } }
Campos de comando
$percentile
usa os seguintes campos:
Campo | Tipo | necessidade | Descrição |
---|---|---|---|
input | Expressão | Obrigatório | $percentile calcula os valores de percentil destes dados. input deve ser um nome de campo ou uma expressão que avalia para um tipo numérico. Se a expressão não puder ser convertida em um tipo numérico, o cálculo $percentile a ignorará. |
p | Expressão | Obrigatório |
|
method | String | Obrigatório | O método que o mongod utiliza para calcular o valor do percentil. O método deve ser 'approximate' . |
Comportamento
Você pode usar $percentile
em:
$group
estágios como acumulador$setWindowFields
estágios como acumulador$project
estágios como uma expressão de agregação
$percentile
possui as seguintes características como acumulador, ele:
Calcula um único resultado para todos os documentos no estágio.
Usa o algoritmot-digest para calcular métricas aproximadas baseadas em percentil.
Usa métodos aproximados para dimensionar grandes volumes de dados.
$percentile
tem as seguintes características como uma expressão de agregação, ela:
Aceita uma array como entrada
Calcula um resultado separado para cada documento de entrada
Tipo de operação
Em uma etapa $group
, $percentile
é um acumulador e calcula um valor para todos os documentos na janela.
Em uma etapa $project
, $percentile
é uma expressão de agregação e calcula valores para cada documento.
Em $setWindowFields
etapas, o $percentile
retorna um resultado para cada documento como uma expressão de agregação, mas os resultados são calculados sobre grupos de documentos como um acumulador.
Considerações de cálculo
Em $group
estágios, o $percentile
sempre utiliza um método de cálculo aproximado.
Em $project
estágios, o $percentile
pode utilizar o método de cálculo discreto mesmo quando o método aproximado é especificado.
Em $setWindowFields
estágios, a carga de trabalho determina o método de cálculo que o $percentile
utiliza.
Os retornos $percentile
dos percentis calculados podem variar, mesmo nos mesmos conjuntos de dados. Isso ocorre porque o algoritmo calcula valores aproximados.
Amostras duplicadas podem causar ambiguidade. Se houver um grande número de duplicatas, os valores percentuais poderão não representar a distribuição real da amostra. Considere um conjunto de dados onde todas as amostras são as mesmas. Todos os valores no conjunto de dados ficam iguais ou abaixo de qualquer percentil. Um valor do "50º percentil" representaria, na verdade, 0 ou 100 por cento das amostras.
$percentile
retorna o valor mínimo para p = 0.0
.
$percentile
retorna o valor máximo para p = 1.0
.
Entrada de array
Se você usar $percentile
como uma expressão de agregação em um estágio $project
, poderá usar uma array como entrada. A sintaxe é:
{ $percentile: { input: [ <expression1, <expression2>, .., <expressionN> ], p: [ <expression1>, <expression2>, ... ], method: <string> } }
Funções de janela
Uma função de janela permite calcular os resultados em uma "janela" móvel de documentos vizinhos. Conforme cada documento passa pelo pipeline, a etapa $setWindowFields
:
Recompute o conjunto de documentos na janela atual
calcula um valor para todos os documentos no conjunto
retorna um único valor para esse documento
Você pode usar $percentile
em um estágio $setWindowFields
para calcular estatísticas contínuas para séries temporais ou outros dados relacionados.
Quando você utiliza $percentile
em uma etapa $setWindowField
, o valor input
deve ser um nome de campo. Se você inserir uma array em vez de um nome de campo, a operação falhará.
Exemplos
Os exemplos a seguir usam a collection testScores
. Criar a collection:
db.testScores.insertMany( [ { studentId: "2345", test01: 62, test02: 81, test03: 80 }, { studentId: "2356", test01: 60, test02: 83, test03: 79 }, { studentId: "2358", test01: 67, test02: 82, test03: 78 }, { studentId: "2367", test01: 64, test02: 72, test03: 77 }, { studentId: "2369", test01: 60, test02: 53, test03: 72 } ] )
Calcular um Valor Único como Acumulador
Crie um acumulador que calcule um único valor percentil:
db.testScores.aggregate( [ { $group: { _id: null, test01_percentiles: { $percentile: { input: "$test01", p: [ 0.95 ], method: 'approximate' } }, } } ] )
Saída:
{ _id: null, test01_percentiles: [ 67 ] }
O valor do campo _id
é null
, portanto, $group
seleciona todos os documentos na coleção.
O acumulador do percentile
obtém seus dados de entrada do campo test01
.
Neste exemplo, a array de percentis, p
, tem um valor, de modo que o operador $percentile
calcula apenas um termo para os dados test01
. O valor do percentil 67
é .
Calcular Vários Valores como Acumulador
Criar um acumulador que calcula vários valores de percentil:
db.testScores.aggregate( [ { $group: { _id: null, test01_percentiles: { $percentile: { input: "$test01", p: [ 0.5, 0.75, 0.9, 0.95 ], method: 'approximate' } }, test02_percentiles: { $percentile: { input: "$test02", p: [ 0.5, 0.75, 0.9, 0.95 ], method: 'approximate' } }, test03_percentiles: { $percentile: { input: "$test03", p: [ 0.5, 0.75, 0.9, 0.95 ], method: 'approximate' } }, test03_percent_alt: { $percentile: { input: "$test03", p: [ 0.9, 0.5, 0.75, 0.95 ], method: 'approximate' } }, } } ] )
Saída:
{ _id: null, test01_percentiles: [ 62, 64, 67, 67 ], test02_percentiles: [ 81, 82, 83, 83 ], test03_percentiles: [ 78, 79, 80, 80 ], test03_percent_alt: [ 80, 78, 79, 80 ] }
O valor do campo _id
é null
, portanto, $group
seleciona todos os documentos na coleção.
O acumulador do percentile
calcula valores para três campos, test01
, test02
e test03
.
O acumulador calcula os valores do percentil 50º, 75º, 90º e 95º para cada campo de entrada.
Os valores de percentil são retornados na mesma ordem que os elementos de p
. Os valores em test03_percentiles
e test03_percent_alt
são os mesmos, mas seu pedido é diferente. A ordem dos elementos em cada array de resultados corresponde à ordem correspondente de elementos no p
.
Usar $percentile
em um $project
estágio
Em uma etapa $project
, $percentile
é uma expressão de agregação e calcula valores para cada documento.
Você pode utilizar um nome de campo ou uma array como entrada em um estágio $project
.
db.testScores.aggregate( [ { $project: { _id: 0, studentId: 1, testPercentiles: { $percentile: { input: [ "$test01", "$test02", "$test03" ], p: [ 0.5, 0.95 ], method: 'approximate' } } } } ] )
Saída:
{ studentId: '2345', testPercentiles: [ 80, 81 ] }, { studentId: '2356', testPercentiles: [ 79, 83 ] }, { studentId: '2358', testPercentiles: [ 78, 82 ] }, { studentId: '2367', testPercentiles: [ 72, 77 ] }, { studentId: '2369', testPercentiles: [ 60, 72 ] }
Quando $percentile
é uma expressão de agregação há um resultado para cada studentId
.
Usar $percentile
em um $setWindowField
estágio
Para basear seus valores de percentil em tendências de dados locais, use $percentile
em um estágio de aggregation pipeline de $setWindowField
.
Este exemplo cria uma janela para filtrar pontuações:
db.testScores.aggregate( [ { $setWindowFields: { sortBy: { test01: 1 }, output: { test01_95percentile: { $percentile: { input: "$test01", p: [ 0.95 ], method: 'approximate' }, window: { range: [ -3, 3 ] } } } } }, { $project: { _id: 0, studentId: 1, test01_95percentile: 1 } } ] )
Saída:
{ studentId: '2356', test01_95percentile: [ 62 ] }, { studentId: '2369', test01_95percentile: [ 62 ] }, { studentId: '2345', test01_95percentile: [ 64 ] }, { studentId: '2367', test01_95percentile: [ 67 ] }, { studentId: '2358', test01_95percentile: [ 67 ] }
Neste exemplo, o cálculo do percentil para cada documento também incorpora dados dos três documentos antes e depois dele.
Saiba mais
O operador $median
é um caso especial do operador $percentile
que utiliza um valor fixo de p: [ 0.5 ]
.
Para mais informações sobre funções da janela, consulte: $setWindowFields
.