-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add resolve aggregation function with tests * add basic aggregation TS types * cleanup * improve comments --------- Co-authored-by: Ciaran Schutte <[email protected]>
- Loading branch information
1 parent
9224979
commit 249608f
Showing
4 changed files
with
147 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,51 @@ | ||
import { SupportedAggregation, SUPPORTED_AGGREGATIONS } from '../common'; | ||
import { Aggregations, NetworkAggregation, NumericAggregations } from '../types'; | ||
|
||
// TODO: implement | ||
export const resolveAggregations = (networkResults: void) => null; | ||
|
||
/** | ||
* Resolve aggregation based on aggregation type | ||
* @param type | ||
* @param aggregations | ||
*/ | ||
export const resolveToNetworkAggregation = <T>( | ||
type: SupportedAggregation, | ||
aggregations: Aggregations[], | ||
) => { | ||
if (type === SUPPORTED_AGGREGATIONS.Aggregations) { | ||
resolveAggregation(aggregations); | ||
} else if (type === SUPPORTED_AGGREGATIONS.NumericAggregations) { | ||
resolveNumericAggregation(aggregations); | ||
} else { | ||
// no types match | ||
throw Error('No matching aggregation type'); | ||
} | ||
}; | ||
|
||
/** | ||
* Takes an array of the same aggregation type and computes the singular type | ||
* eg. NumericAggregation => NetworkNumericAggregation | ||
* | ||
* @param aggregations | ||
* @returns | ||
*/ | ||
export const resolveAggregation = (aggregations: Aggregations[]): NetworkAggregation => { | ||
const emptyAggregation: NetworkAggregation = { bucket_count: 0, buckets: [] }; | ||
|
||
const resolvedAggregation = aggregations.reduce((resolvedAggregation, agg) => { | ||
const computedBucketCount = resolvedAggregation.bucket_count + agg.bucket_count; | ||
const computedBuckets = agg.buckets.map(({ key, doc_count }) => { | ||
// potentially expensive "find" if array of buckets is very large | ||
const bucket = resolvedAggregation.buckets.find((bucket) => bucket.key === key); | ||
return { key, doc_count: (bucket?.doc_count || 0) + doc_count }; | ||
}); | ||
return { bucket_count: computedBucketCount, buckets: computedBuckets }; | ||
}, emptyAggregation); | ||
return resolvedAggregation; | ||
}; | ||
|
||
const resolveNumericAggregation = (aggregations: NumericAggregations) => { | ||
// TODO: implement | ||
throw Error('Not implemented'); | ||
}; |
27 changes: 27 additions & 0 deletions
27
modules/server/src/network/aggregations/tests/aggregation.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { resolveAggregation } from '..'; | ||
import { aggregation } from './fixture'; | ||
|
||
describe('Aggregation', () => { | ||
it('should resolve multiple objects of type Aggregation into a single object of type NetworkAggregation', () => { | ||
const result = resolveAggregation([aggregation.inputA, aggregation.inputB]); | ||
|
||
const resultForMaleCount = | ||
result.buckets.find((bucket) => bucket.key === 'Male')?.doc_count || 0; | ||
const resultForFemaleCount = | ||
result.buckets.find((bucket) => bucket.key === 'Female')?.doc_count || 0; | ||
|
||
const expectedMaleCount = | ||
(aggregation.inputA.buckets.find((bucket) => bucket.key === 'Male')?.doc_count || 0) + | ||
(aggregation.inputB.buckets.find((bucket) => bucket.key === 'Male')?.doc_count || 0); | ||
|
||
const expectedFemaleCount = | ||
(aggregation.inputA.buckets.find((bucket) => bucket.key === 'Female')?.doc_count || 0) + | ||
(aggregation.inputB.buckets.find((bucket) => bucket.key === 'Female')?.doc_count || 0); | ||
|
||
expect(result.bucket_count).toEqual( | ||
aggregation.inputA.bucket_count + aggregation.inputB.bucket_count, | ||
); | ||
expect(resultForMaleCount).toEqual(expectedMaleCount); | ||
expect(resultForFemaleCount).toEqual(expectedFemaleCount); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { Aggregations } from '@/network/types'; | ||
|
||
// Aggregation | ||
const inputA: Aggregations = { | ||
bucket_count: 82, | ||
buckets: [ | ||
{ | ||
key: 'Male', | ||
doc_count: 70, | ||
}, | ||
{ | ||
key: 'Female', | ||
doc_count: 12, | ||
}, | ||
], | ||
}; | ||
|
||
const inputB: Aggregations = { | ||
bucket_count: 715, | ||
buckets: [ | ||
{ | ||
key: 'Male', | ||
doc_count: 15, | ||
}, | ||
{ | ||
key: 'Female', | ||
doc_count: 700, | ||
}, | ||
], | ||
}; | ||
|
||
const inputC: Aggregations = { | ||
bucket_count: 1565, | ||
buckets: [ | ||
{ | ||
key: 'Male', | ||
doc_count: 765, | ||
}, | ||
{ | ||
key: 'Female', | ||
doc_count: 800, | ||
}, | ||
{ | ||
key: 'Unknown', | ||
doc_count: 0, | ||
}, | ||
], | ||
}; | ||
|
||
export const aggregation = { | ||
inputA, | ||
inputB, | ||
inputC, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters