Skip to main content

Add Window Fields

Adds field(s) by performing operations on a specified span of records, known as a window.

Operations can include:

  • Getting the rank of a record, given a specified sort order.
  • Aggregating across the window to find mean, min, max, sum, etc.

Examples Below:

Calculate a Rank (No partitioning)

note

Windows are defined by partitioning. When a partition isn't specified, there is just one window and it contains all records.

Input records:

ProductScore
Product 010.3461
Product 020.3096
Product 030.7573
Product 040.8856
Product 050.3959

Stage definition:

We are defining a stage that will sort the input records by Score (highest first) and return a rank.

{
$addWindowFields: {

// note: No partitioning defined, so the window is all records.

// sort is required for ranking
sortBy: {
[ field: "Score", order: "descending" ]
},

// new output field to add
output: {
HighScoreRank: "rank()" // rank() is the operation
}
}
}

Output records:

note

Notice below that 'Product 04' has the highest score and received a rank of 1. 'Product 02' has the lowest score and received a rank of 5.

ProductScoreHighScoreRank
Product 010.34614
Product 020.30965
Product 030.75732
Product 040.88561
Product 050.39593

Calculate a Rank within Window

Input records:

CountryProductScore
USAProduct 010.3461
USAProduct 020.3096
USAProduct 030.7573
USAProduct 040.8856
USAProduct 050.3959
CanadaProduct 010.4744
CanadaProduct 020.7804
CanadaProduct 030.7071
CanadaProduct 040.2232
CanadaProduct 050.5828

Stage definition:

This stage definition is similar to the example above, but we are adding partitioning by Country. This means that there will be a window for each Country, and a separate ranking will be calculated for each window.

{
$addWindowFields: {

// this defines the window
paritionBy: "Country",

// sort is required for ranking
sortBy: {
[ field: "Score", order: "descending" ]
},

// new output field to add
output: {
HighScoreRankWithinCountry: "rank()" // this is the window operation
}
}
}

Output records:

note

Notice that the ranking occurs within country, because partitioning made each country a separate window.

CountryProductScoreHighScoreRankWithinCountry
USAProduct 010.34614
USAProduct 020.30965
USAProduct 030.75732
USAProduct 040.88561
USAProduct 050.39593
CanadaProduct 010.47444
CanadaProduct 020.78041
CanadaProduct 030.70712
CanadaProduct 040.22325
CanadaProduct 050.58283

Calculate a Net

In this example we will average across records (rows).

tip

Taking an average across fields (columns) would be done using the AddFields stage.

Input records:

CountryProductScore
USAProduct 010.3461
USAProduct 020.3096
USAProduct 030.7573
USAProduct 040.8856
USAProduct 050.3959
CanadaProduct 010.4744
CanadaProduct 020.7804
CanadaProduct 030.7071
CanadaProduct 040.2232
CanadaProduct 050.5828

Stage definition:

This time we are defining two output fields. One calculates an average and one calculates a max. And since we are partitioning by Country, a separate calculation window will be created for each country.

{
$addWindowFields: {

// this defines the window (optional)
paritionBy: "Country",

// note: sort is not required because we aren't ranking

// new output field to add
output: {
AverageScore: "avg(Score)"
HighScore: "max(Score)"
}
}
}

Output records:

note

Notice that since the average and max calculations below were windowed by Country, one AverageScore is shared by all USA records, and a different AverageScore is shared by Canada records.

CountryProductScoreAverageScoreHighScore
USAProduct 010.34610.53890.8856
USAProduct 020.30960.53890.8856
USAProduct 030.75730.53890.8856
USAProduct 040.88560.53890.8856
USAProduct 050.39590.53890.8856
CanadaProduct 010.47440.553580.7804
CanadaProduct 020.78040.553580.7804
CanadaProduct 030.70710.553580.7804
CanadaProduct 040.22320.553580.7804
CanadaProduct 050.58280.553580.7804
tip

As a next step, you could calculate a gap by appending an AddFields stage that subtracts a product's score from the average.