Skip to content

Commit

Permalink
Merge pull request #413 from BaseAdresseNationale/feat/update-compute…
Browse files Browse the repository at this point in the history
…-stats

Feat/update compute stats
  • Loading branch information
antoineludeau authored Jun 18, 2024
2 parents b834c5f + 4a0919b commit d54f6a2
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 47 deletions.
194 changes: 147 additions & 47 deletions lib/models/ban.cjs
Original file line number Diff line number Diff line change
@@ -1,71 +1,171 @@
const {sumBy} = require('lodash')
const mongo = require('../util/mongo.cjs')
const {getCommunes, getCommune} = require('../util/cog.cjs')

async function computeStats() {
const communes = getCommunes()
const defaultStatsOfDistrictsDataResult = {
nbAdresses: 0,
nbAdressesCertifiees: 0,
nbCommunesCouvertes: 0,
populationCouverte: 0,
nbCommunesAvecBanId: 0,
nbAdressesAvecBanId: 0,
}

const defaultStatsOfAddressesDataResult = {
nbNumeroWithBanId: 0,
countDistinctCodeCommune: 0,
}

const france = {
population: sumBy(communes, 'population'),
nbCommunes: communes.length
async function getStatsOfDistricts(cog = []) {
const communesCollection = mongo.db.collection('communes')
const mongoRequestFilters = {
ban: null,
bal: {typeComposition: 'bal'},
computed: {typeComposition: {$ne: 'bal'}},
}
const statsOfDistrictsPipelineResult = groupName => (
{
$group: {
_id: `group_${groupName}`,
nbAdresses: {$sum: '$nbNumeros'},
nbAdressesCertifiees: {$sum: '$nbNumerosCertifies'},
nbCommunesCouvertes: {$sum: 1},
populationCouverte: {$sum: '$population'},
nbCommunesIdSocle: {$sum: {
$cond: [{$eq: ['$withBanId', true]}, 1, 0]
}},
nbAdressesIdSocle: {$sum: {
$cond: [{$eq: ['$withBanId', true]}, '$nbNumeros', 0]
}}
}
}
)

const communesRecords = await mongo.db.collection('communes').find({}).toArray()
const banCommunesRecords = communesRecords.filter(c => c.nbNumeros > 0)
const mongoRequest = [
...(cog && cog.length > 0 ? [{$match: {codeCommune: {$in: cog}}}] : []),
{
$facet: Object.fromEntries(
Object
.entries(mongoRequestFilters)
.map(([groupName, filter]) => [
groupName, [
...(filter ? [{$match: filter}] : []),
statsOfDistrictsPipelineResult(groupName)
]
])
)
}
]

const ban = {
nbAdresses: sumBy(banCommunesRecords, 'nbNumeros'),
nbAdressesCertifiees: sumBy(banCommunesRecords, 'nbNumerosCertifies'),
nbCommunesCouvertes: banCommunesRecords.length,
populationCouverte: sumBy(banCommunesRecords, 'population'),
nbCommunesAvecBanId: sumBy(banCommunesRecords, 'withBanId')
return communesCollection.aggregate(mongoRequest).toArray()
}

async function getStatsOfAddresses(cog) {
const numerosCollection = mongo.db.collection('numeros')
const mongoRequestFilters = {
ban: null,
bal: {sources: 'bal'},
computed: {sources: {$not: {$eq: ['bal']}}},
}

const balCommunesRecords = communesRecords.filter(c => c.typeComposition === 'bal')
const statsOfBanIdPipelinesResult = [
{
$group: {
_id: null,
nbNumeroWithBanId: {$sum: 1},
distinctCodeCommune: {$addToSet: '$codeCommune'}
}
},
{
$project: {
_id: 0,
nbNumeroWithBanId: '$nbNumeroWithBanId',
countDistinctCodeCommune: {$size: '$distinctCodeCommune'}
}
},
]

const bal = {
nbAdresses: sumBy(balCommunesRecords, 'nbNumeros'),
nbAdressesCertifiees: sumBy(balCommunesRecords, 'nbNumerosCertifies'),
nbCommunesCouvertes: balCommunesRecords.length,
populationCouverte: sumBy(balCommunesRecords, 'population'),
nbCommunesAvecBanId: sumBy(balCommunesRecords, 'withBanId')
}
const mongoRequest = [
...(cog && cog.length > 0 ? [{$match: {codeCommune: {$in: cog}}}] : []),
{$match: {banId: {$exists: true, $ne: null}}},
{
$facet: Object.fromEntries(
Object
.entries(mongoRequestFilters)
.map(([groupName, filter]) => [
groupName, [
...(filter ? [{$match: filter}] : []),
...statsOfBanIdPipelinesResult,
]
])
)
}
]

return {france, ban, bal}
return numerosCollection.aggregate(mongoRequest).toArray()
}

async function computeFilteredStats(codesCommune) {
const communes = codesCommune.map(code => getCommune(code))
async function getFullStats(codesCommune) {
const statsByCog = getStatsOfDistricts(codesCommune)
const statsOfNumerosCollection = getStatsOfAddresses(codesCommune)

const total = {
population: sumBy(communes, 'population'),
nbCommunes: communes.length
const [
[{ban: banDistrictStat, bal: balDistrictStat, computed: computedDistrictStat}],
[{ban: banBanIdStat, bal: balBanIdStat, computed: computedBanIdStat}],
] = await Promise.all([statsByCog, statsOfNumerosCollection])

const ban = {
...defaultStatsOfDistrictsDataResult,
...banDistrictStat?.[0],
...defaultStatsOfAddressesDataResult,
...banBanIdStat?.[0],
}

const bal = {
...defaultStatsOfDistrictsDataResult,
...balDistrictStat?.[0],
...defaultStatsOfAddressesDataResult,
...balBanIdStat?.[0],
}

const communesRecords = await mongo.db.collection('communes').find({
codeCommune: {$in: codesCommune}
}).toArray()
const banCommunesRecords = communesRecords.filter(c => c.nbNumeros > 0)
const computed = {
...defaultStatsOfDistrictsDataResult,
...computedDistrictStat?.[0],
...defaultStatsOfAddressesDataResult,
...computedBanIdStat?.[0],
}

const ban = {
nbAdresses: sumBy(banCommunesRecords, 'nbNumeros'),
nbAdressesCertifiees: sumBy(banCommunesRecords, 'nbNumerosCertifies'),
nbCommunesCouvertes: banCommunesRecords.length,
populationCouverte: sumBy(banCommunesRecords, 'population'),
nbCommunesAvecBanId: sumBy(banCommunesRecords, 'withBanId')
const total = {
population: ban?.populationCouverte || 0,
nbCommunes: ban?.nbCommunesCouvertes || 0,
}

return {
total,
ban,
bal,
computed,
}
}

const balCommunesRecords = communesRecords.filter(c => c.typeComposition === 'bal')
async function computeStats() {
const {total, ban, bal, computed} = await getFullStats()

const bal = {
nbAdresses: sumBy(balCommunesRecords, 'nbNumeros'),
nbAdressesCertifiees: sumBy(balCommunesRecords, 'nbNumerosCertifies'),
nbCommunesCouvertes: balCommunesRecords.length,
populationCouverte: sumBy(balCommunesRecords, 'population'),
nbCommunesAvecBanId: sumBy(balCommunesRecords, 'withBanId')
return {
france: total,
ban,
bal,
assemblage: computed,
}
}

return {total, ban, bal}
async function computeFilteredStats(codesCommune) {
const {total, ban, bal, computed} = await getFullStats(codesCommune)

return {
total,
ban,
bal,
assemblage: computed,
}
}

module.exports = {computeStats, computeFilteredStats}
2 changes: 2 additions & 0 deletions lib/util/mongo.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ class Mongo {
await this.db.collection('numeros').createIndex({banIdSecondaryCommonToponyms: 1})
await this.db.collection('numeros').createIndex({banIdDistrict: 1})
await this.db.collection('numeros').createIndex({tiles: 1})
await this.db.collection('numeros').createIndex({sources: 1})
await this.db.collection('pseudo_codes_voies').createIndex({codeCommune: 1})
await this.db.collection('sources_adresses').createIndex({codeCommune: 1, dataSource: 1})
await this.db.collection('sources_parts').createIndex({source: 1, part: 1})
await this.db.collection('sources_communes').createIndex({codeCommune: 1, source: 1})
await this.db.collection('sources_communes').createIndex({source: 1, part: 1})
await this.db.collection('communes').createIndex({compositionAskedAt: 1}, {sparse: true})
await this.db.collection('communes').createIndex({codeCommune: 1}, {unique: true})
await this.db.collection('communes').createIndex({typeComposition: 1})
await this.db.collection('communes').createIndex({banId: 1})
await this.db.collection('metrics').createIndex({name: 1, date: 1}, {unique: true})
}
Expand Down

0 comments on commit d54f6a2

Please sign in to comment.