import _ from 'lodash' ; import { Db } from 'mongodb' ; import config from '../config' ; import { SurveyConfig } from '../types' ; import { Filters , generateFiltersQuery } from '../filters' ; export async function computeChoicesOverYearsGraph ( db , survey , field , filters ? ) { const collection = db . collection ( config . mongo . normalized_collection ) ; const results = await collection . aggregate < { years : Array < { year : number ; choice : string ; } > ; } > ( [ { $match : generateFiltersQuery ( filters ) } , { $project : { _id : 0 , email : { $trim : { input : '$user_info.email' } } , year : true , choice : `$${ field }` } } , { $match : { email : { $nin : [ null , '' , ' ' ] } , year : { $nin : [ null , '' , ' ' ] } , choice : { $nin : [ null , '' , ' ' ] } } } , { $group : { _id : { email : '$email' , year : '$year' } , email : { $last : '$email' } , year : { $last : '$year' } , choice : { $last : '$choice' } } } , { $sort : { email : 1 , year : 1 } } , { $group : { _id : '$email' , yearCount : { $sum : 1 } , years : { $push : { year : '$year' , choice : '$choice' } } } } , { $match : { yearCount : { $gt : 1 } } } , { $project : { _id : 0 , years : true } } ] ) . toArray ( ) ; let nodes = [ ] ; let links = [ ] ; await results . forEach ( item => { item . years . forEach ( ( current , index , arr ) => { const currentId = `${ current . year }.${ current . choice }` ; if ( nodes . find ( n => n . id === currentId ) === undefined ) { nodes . push ( { id : currentId , ... current } ) ; } if ( index > 0 ) { const previous = arr [ index - 1 ] ; if ( current . year - previous . year === 1 ) { const previousId = `${ previous . year }.${ previous . choice }` ; let link = links . find ( l => { return l . source === previousId && l . target === currentId ; } ) ; if ( ! link ) { link = { source : previousId , target : currentId , count : 0 } ; links . push ( link ) ; } link . count += 1 ; } } } ) ; } ) ; nodes = _ . orderBy ( nodes , 'year' ) ; links = _ . orderBy ( links , 'count' ) ; links . reverse ( ) ; return { nodes , links } ; }