Menu Docs
Página inicial do Docs
/
Manual do banco de dados
/ / /

$fill ( operador de expressão )

$fill

Novidades na versão 5.3.

Preenche null e os valores de campo ausentes nos documentos.

Você pode utilizar o $fill para preencher pontos de dados ausentes:

  • Em uma sequência baseada em valores circundantes.

  • Com um valor fixo.

O estágio $fill tem esta sintaxe:

{
$fill: {
partitionBy: <expression>,
partitionByFields: [ <field 1>, <field 2>, ... , <field n> ],
sortBy: {
<sort field 1>: <sort order>,
<sort field 2>: <sort order>,
...,
<sort field n>: <sort order>
},
output: {
<field 1>: { value: <expression> },
<field 2>: { method: <string> },
...
}
}
}

O estágio $fill toma um documento com estes campos:

Campo
necessidade
Descrição

partitionBy

Opcional

Especifica uma expressão para agrupar os documentos. Na etapa, um grupo de $fill documentos é conhecido como uma partição.

Se você omitir partitionBy e partitionByFields, o usará uma partição para toda a$fill coleção.

partitionBy e partitionByFields são mutuamente exclusivos.

Veja um exemplo.

Opcional

Especifica uma array de campos como a chave composta para agrupar os documentos. No estágio, cada grupo de $fill documentos é conhecido como uma partição.

Se você omitir partitionBy e partitionByFields, o usará uma partição para toda a$fill coleção.

partitionBy e partitionByFields são mutuamente exclusivos.

partitionByFields Consulte Restrições do.

Necessário se o método for especificado em pelo menos uma <field>saída..

Caso contrário, opcional.

Especifica o campo ou campos para classificar os documentos dentro de cada partição. Utiliza a mesma sintaxe que o estágio $sort.

Obrigatório

Especifica um objeto contendo cada campo para o qual preencher os valores ausentes. Você pode especificar vários campos no objeto saída.

O nome do objeto é o nome do campo a ser preenchido. O valor do objeto especifica como o campo é preenchido.

Obrigatório

Especifica um objeto indicando como preencher valores ausentes no campo de destino.

O nome do objeto deve ser value ou method. Se o nome for:

$fill retorna um erro se houver algum nome de campo na array partitionByFields:

  • Avalia para um valor não string.

  • Começa com $.

O método de preenchimento linear preenche campos null e ausentes usando interpolação linear com base nos valores não-null circundantes na sequência.

  • Para cada documento em que o campo é null ou ausente, linearFill preenche esses campos na proporção do intervalo de valores ausentes entre os valores não circundantes,null de acordo com a ordem SortBy . Para determinar os valores para campos ausentes, o linearFill utiliza:

    • A diferença entre os valores circundantes que não sãonull.

    • O número de null campos para preencher entre os valores circundantes.

  • O método linear pode preencher vários valores de null consecutivos se esses valores forem precedidos e seguidos por valores nãonull de acordo com a ordem sortBy .

    Exemplo

    Se uma coleção contiver estes documentos:

    { index: 0, value: 0 },
    { index: 1, value: null },
    { index: 2, value: null },
    { index: 3, value: null },
    { index: 4, value: 10 }

    Após utilizar o método de preenchimento linear para preencher os valores null, os documentos tornam-se:

    { index: 0, value: 0 },
    { index: 1, value: 2.5 },
    { index: 2, value: 5 },
    { index: 3, value: 7.5 },
    { index: 4, value: 10 }
  • null valores que não são precedidos e seguidos por valores diferentes denull permanecem null.

  • Para usar o método de preenchimento linear, você também deve usar o campo sortBy para classificar os dados.

    • Ao usar o método de preenchimento linear, $fill retorna um erro se houver algum valor repetido no campo sortBy em uma única partição.

Para um exemplo completo utilizando o método de preenchimento linear, consulte Preencher valores de campo ausentes com interpolação linear.

locf significa a última observação realizada.

  • Se um campo que está sendo preenchido contiver valores null e não nulos, locf definirá os valores null e ausentes como o último valor não nulo conhecido do campo, de acordo com a ordem sortBy.

    • Se o campo contiver apenas null ou valores ausentes em uma partição, locf definirá o valor do campo como null para essa partição.

    • null e os valores de campo ausentes que aparecem antes dos valores não nulos na ordem de classificação permanecem null.

  • Para usar o método de preenchimento locf, você também deve usar o campo sortBy para classificar os dados.

Para um exemplo completo utilizando o método de preenchimento locf, consulte Preencher Valores de Campo Faltando Baseado no Último Valor Observado.

Para preencher null e os valores de campo ausentes em um documento, você pode usar:

  • O estágio $fill.

    Quando você utiliza o estágio $fill, o campo que você especifica na saída é o mesmo campo utilizado como os dados de origem.

  • Os operadores de agregação $linearFill e $locf.

    Quando você $linearFill ou $locf, você pode configurar valores para um campo diferente do campo utilizado como os dados de origem.

Os exemplos nesta seção mostram como utilizar o $fill para preencher valores ausentes:

Uma loja de calçados mantém uma coleção dailySales que contém um documento resumindo as vendas de cada dia. A loja de sapatos vende estes tipos de sapatos:

  • boots

  • sandals

  • sneakers

Crie a seguinte coleção do dailySales:

db.dailySales.insertMany( [
{
"date": ISODate("2022-02-02"),
"bootsSold": 10,
"sandalsSold": 20,
"sneakersSold": 12
},
{
"date": ISODate("2022-02-03"),
"bootsSold": 7,
"sneakersSold": 18
},
{
"date": ISODate("2022-02-04"),
"sneakersSold": 5
}
] )

Nem todos os documentos na coleção dailySales contêm cada tipo de sapato. Se um tipo de sapato estiver faltando, significa que não havia sapatos desse tipo vendidos na data correspondente.

O exemplo a seguir usa $fill para definir as quantidades vendidas para 0 para os tipos de sapatos ausentes para as vendas de cada dia:

db.dailySales.aggregate( [
{
$fill:
{
output:
{
"bootsSold": { value: 0 },
"sandalsSold": { value: 0 },
"sneakersSold": { value: 0 }
}
}
}
] )

No pipeline anterior:

  • $fill preenche valores para campos em falta.

  • saída especifica:

  • Os nomes dos campos para preencher.

  • O valor para definir os campos preenchidos. Neste exemplo, o
    saída especifica um valor constante de 0.

Saída de exemplo:

[
{
_id: ObjectId("6202df9f394d47411658b51e"),
date: ISODate("2022-02-02T00:00:00.000Z"),
bootsSold: 10,
sandalsSold: 20,
sneakersSold: 12
},
{
_id: ObjectId("6202df9f394d47411658b51f"),
date: ISODate("2022-02-03T00:00:00.000Z"),
bootsSold: 7,
sneakersSold: 18,
sandalsSold: 0
},
{
_id: ObjectId("6202df9f394d47411658b520"),
date: ISODate("2022-02-04T00:00:00.000Z"),
sneakersSold: 5,
bootsSold: 0,
sandalsSold: 0
}
]

Crie uma coleção stock que contenha os seguintes documentos, que acompanham o preço das ações de uma única empresa em intervalos de hora em hora:

db.stock.insertMany( [
{
time: ISODate("2021-03-08T09:00:00.000Z"),
price: 500
},
{
time: ISODate("2021-03-08T10:00:00.000Z"),
},
{
time: ISODate("2021-03-08T11:00:00.000Z"),
price: 515
},
{
time: ISODate("2021-03-08T12:00:00.000Z")
},
{
time: ISODate("2021-03-08T13:00:00.000Z")
},
{
time: ISODate("2021-03-08T14:00:00.000Z"),
price: 485
}
] )

O campo price está faltando em alguns documentos da coleção.

Para preencher os price valores de ausentes utilizando interpolação linear, utilize com $fill o linear método de preenchimento:

db.stock.aggregate( [
{
$fill:
{
sortBy: { time: 1 },
output:
{
"price": { method: "linear" }
}
}
}
] )

No pipeline anterior:

  • $fill preenche valores para campos em falta.

  • sortBy: { time: 1 } classifica os documentos pelo campo time em ordem crescente, do mais antigo ao mais recente.

  • saída especifica:

  • price como o campo para o qual preencher os valores ausentes.

  • { method: "linear" } como método de preenchimento. O preenchimento linear
    O método preenche price os valores ausentes usando interpolação linear com base nos price valores adjacentes na sequência.

Saída de exemplo:

[
{
_id: ObjectId("620ad41c394d47411658b5e9"),
time: ISODate("2021-03-08T09:00:00.000Z"),
price: 500
},
{
_id: ObjectId("620ad41c394d47411658b5ea"),
time: ISODate("2021-03-08T10:00:00.000Z"),
price: 507.5
},
{
_id: ObjectId("620ad41c394d47411658b5eb"),
time: ISODate("2021-03-08T11:00:00.000Z"),
price: 515
},
{
_id: ObjectId("620ad41c394d47411658b5ec"),
time: ISODate("2021-03-08T12:00:00.000Z"),
price: 505
},
{
_id: ObjectId("620ad41c394d47411658b5ed"),
time: ISODate("2021-03-08T13:00:00.000Z"),
price: 495
},
{
_id: ObjectId("620ad41c394d47411658b5ee"),
time: ISODate("2021-03-08T14:00:00.000Z"),
price: 485
}
]

Crie uma coleção restaurantReviews que contenha os seguintes documentos, que armazenam as pontuações das avaliações de um único restaurante ao longo do tempo:

db.restaurantReviews.insertMany( [
{
date: ISODate("2021-03-08"),
score: 90
},
{
date: ISODate("2021-03-09"),
score: 92
},
{
date: ISODate("2021-03-10")
},
{
date: ISODate("2021-03-11")
},
{
date: ISODate("2021-03-12"),
score: 85
},
{
date: ISODate("2021-03-13")
}
] )

O campo score está faltando em alguns documentos da coleção.

Para preencher os campos de score ausentes e garantir que não haja lacunas nos dados, use $fill. No exemplo seguinte, $fill usa o método locf para preencher os valores de score ausentes com a score anterior na sequência:

db.restaurantReviews.aggregate( [
{
$fill:
{
sortBy: { date: 1 },
output:
{
"score": { method: "locf" }
}
}
}
] )

No pipeline anterior:

  • $fill preenche os valores ausentes de score.

  • sortBy: { date: 1 } classifica os documentos pelo campo date em ordem crescente, do mais antigo ao mais recente.

  • saída especifica:

  • score como o campo para o qual preencher os valores ausentes.

  • { method: "locf" } como método de preenchimento. O preenchimento locf
    O método preenche os valores score ausentes com o último score observado na sequência.

Saída de exemplo:

[
{
_id: ObjectId("62040bc9394d47411658b553"),
date: ISODate("2021-03-08T00:00:00.000Z"),
score: 90
},
{
_id: ObjectId("62040bc9394d47411658b554"),
date: ISODate("2021-03-09T00:00:00.000Z"),
score: 92
},
{
_id: ObjectId("62040bc9394d47411658b555"),
date: ISODate("2021-03-10T00:00:00.000Z"),
score: 92
},
{
_id: ObjectId("62040bc9394d47411658b556"),
date: ISODate("2021-03-11T00:00:00.000Z"),
score: 92
},
{
_id: ObjectId("62040bc9394d47411658b557"),
date: ISODate("2021-03-12T00:00:00.000Z"),
score: 85
},
{
_id: ObjectId("62040bc9394d47411658b558"),
date: ISODate("2021-03-13T00:00:00.000Z"),
score: 85
}
]

Considere o exemplo anterior com avaliações de restaurantes, mas em vez de rastrear um único restaurante, a coleção agora contém avaliações de vários restaurantes.

Crie uma coleção denominada restaurantReviewsMultiple e preencha a coleção com estes documentos:

db.restaurantReviewsMultiple.insertMany( [
{
date: ISODate("2021-03-08"),
restaurant: "Joe's Pizza",
score: 90
},
{
date: ISODate("2021-03-08"),
restaurant: "Sally's Deli",
score: 75
},
{
date: ISODate("2021-03-09"),
restaurant: "Joe's Pizza",
score: 92
},
{
date: ISODate("2021-03-09"),
restaurant: "Sally's Deli"
},
{
date: ISODate("2021-03-10"),
restaurant: "Joe's Pizza"
},
{
date: ISODate("2021-03-10"),
restaurant: "Sally's Deli",
score: 68
},
{
date: ISODate("2021-03-11"),
restaurant: "Joe's Pizza",
score: 93
},
{
date: ISODate("2021-03-11"),
restaurant: "Sally's Deli"
}
] )

O campo score está faltando em alguns documentos da coleção.

Para preencher os campos de score ausentes e garantir que não haja lacunas nos dados, use $fill. No exemplo seguinte, $fill usa o método locf para preencher os valores de score ausentes com a score anterior na sequência:

db.restaurantReviewsMultiple.aggregate( [
{
$fill:
{
sortBy: { date: 1 },
partitionBy: { "restaurant": "$restaurant" },
output:
{
"score": { method: "locf" }
}
}
}
] )

No pipeline anterior:

  • $fill preenche os valores ausentes de score.

  • sortBy: { date: 1 } classifica os documentos pelo campo date em ordem crescente, do mais antigo ao mais recente.

  • partitionBy: { "restaurant": "$restaurant" } partições dos dados de restaurant. Existem dois restaurantes: Joe's Pizza e Sally's Deli.

  • saída especifica:

  • score como o campo para o qual preencher os valores ausentes.

  • { method: "locf" } como método de preenchimento. O preenchimento locf
    O método preenche os valores score ausentes com o último score observado na sequência.

Saída de exemplo:

[
{
_id: ObjectId("620559f4394d47411658b58f"),
date: ISODate("2021-03-08T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 90
},
{
_id: ObjectId("620559f4394d47411658b591"),
date: ISODate("2021-03-09T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 92
},
{
_id: ObjectId("620559f4394d47411658b593"),
date: ISODate("2021-03-10T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 92
},
{
_id: ObjectId("620559f4394d47411658b595"),
date: ISODate("2021-03-11T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 93
},
{
_id: ObjectId("620559f4394d47411658b590"),
date: ISODate("2021-03-08T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 75
},
{
_id: ObjectId("620559f4394d47411658b592"),
date: ISODate("2021-03-09T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 75
},
{
_id: ObjectId("620559f4394d47411658b594"),
date: ISODate("2021-03-10T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 68
},
{
_id: ObjectId("620559f4394d47411658b596"),
date: ISODate("2021-03-11T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 68
}
]

Quando você preenche valores ausentes, a saída não indica se um valor foi preenchido com o operador $fill ou se o valor existia no documento originalmente. Para distinguir entre valores preenchidos e preexistentes, você pode usar um estágio $set antes de $fill e definir um novo campo com base na existência ou não do valor.

Por exemplo, crie uma coleção restaurantReviews que contenha os seguintes documentos, que armazenam as pontuações das avaliações de um restaurante ao longo do tempo:

db.restaurantReviews.insertMany( [
{
date: ISODate("2021-03-08"),
score: 90
},
{
date: ISODate("2021-03-09"),
score: 92
},
{
date: ISODate("2021-03-10")
},
{
date: ISODate("2021-03-11")
},
{
date: ISODate("2021-03-12"),
score: 85
},
{
date: ISODate("2021-03-13")
}
] )

O campo score está faltando em alguns documentos da coleção. Você pode preencher os valores score ausentes usando o operador $fill.

Crie um pipeline para executar as seguintes ações:

  • Use para adicionar um novo campo a cada documento , indicando se o campo do $set documento score existe antes do $fill operador preencher os valores. Este novo campo é valueExisted chamado.

  • Preencha os valores score ausentes com o último score observado na sequência. O método de preenchimento locf significa "última observação realizada adiante".

O pipeline se assemelha ao seguinte código:

db.restaurantReviews.aggregate( [
{
$set: {
"valueExisted": {
"$ifNull": [
{ "$toBool": { "$toString": "$score" } },
false
]
}
}
},
{
$fill: {
sortBy: { date: 1 },
output:
{
"score": { method: "locf" }
}
}
}
] )

Observação

Manipulação de valores de zero

Na expressão $ifNull, os valores score são convertidos em strings e, em seguida, em booleanos. A expressão $toBool sempre converte strings em true. Se os valores de score não forem convertidos em strings, os valores de score de 0 terão valueExisted definido para false.

Saída:

[
{
_id: ObjectId("63595116b1fac2ee2e957f15"),
date: ISODate("2021-03-08T00:00:00.000Z"),
score: 90,
valueExisted: true
},
{
_id: ObjectId("63595116b1fac2ee2e957f16"),
date: ISODate("2021-03-09T00:00:00.000Z"),
score: 92,
valueExisted: true
},
{
_id: ObjectId("63595116b1fac2ee2e957f17"),
date: ISODate("2021-03-10T00:00:00.000Z"),
valueExisted: false,
score: 92
},
{
_id: ObjectId("63595116b1fac2ee2e957f18"),
date: ISODate("2021-03-11T00:00:00.000Z"),
valueExisted: false,
score: 92
},
{
_id: ObjectId("63595116b1fac2ee2e957f19"),
date: ISODate("2021-03-12T00:00:00.000Z"),
score: 85,
valueExisted: true
},
{
_id: ObjectId("63595116b1fac2ee2e957f1a"),
date: ISODate("2021-03-13T00:00:00.000Z"),
valueExisted: false,
score: 85
}
]

Os exemplos do Node.js nesta página usam a sample_weatherdata.data collection dos conjuntos de dados de amostra do Atlas . Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js

Para usar o driver Node.js do MongoDB para adicionar um estágio $fill a um pipeline de agregação , use o operador $fill em um objeto de pipeline.

O exemplo a seguir cria um pipeline que preenche valores nulos ou ausentes. O pipeline inclui os seguintes estágios:

  • O estágio agrupa documentos de entrada por $group seu ts campo e calcula a média seaSurfaceTemperature.value de cada grupo.

  • O estágio classifica os dados agrupados $fill pelo _id campo em ordem crescente e preenche valores nulos ou seaSurfaceTemperature ausentes usando interpolação linear.

const pipeline = [
{
$group: {
_id: "$ts",
seaSurfaceTemperature: { $avg: "$seaSurfaceTemperature.value" },
}
},
{
$fill: {
sortBy: { _id: 1 },
output: { seaSurfaceTemperature: { method: "linear" } }
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

Voltar

$facet

Nesta página