diff --git a/backend/web/server/plugins/cyberleague/functions.js b/backend/web/server/plugins/cyberleague/functions.js index 82552ce620..1ddf789456 100644 --- a/backend/web/server/plugins/cyberleague/functions.js +++ b/backend/web/server/plugins/cyberleague/functions.js @@ -133,6 +133,7 @@ USER_MODELS.forEach(m => { options: { ref: 'score' } }, }) + declareComputedField({model: m, field: 'related_users', requires:'function,company.size,company.sector,shortname', getterFn: getRelated('user')}) }) //Company declarations diff --git a/backend/web/server/plugins/cyberleague/related.js b/backend/web/server/plugins/cyberleague/related.js index 5615063f12..5cada601c4 100644 --- a/backend/web/server/plugins/cyberleague/related.js +++ b/backend/web/server/plugins/cyberleague/related.js @@ -13,6 +13,103 @@ const getRelated = (model) => { return lodash.orderBy(lodash.filter(companies, (c) => !idEqual(data._id,c._id)), (c) => compareCompanies(c, data.expertise_set?.expertises), `desc`).slice(0, 10) } } + + if (model == `user`) { + return async (userId,params,data) => { + + const loadedUsers = await loadFromDb({model: `user`, fields: [`function`, `company.size`,`company.sector`,`shortname`]}) + let users = lodash.filter(loadedUsers, (u) => !idEqual(data._id,u._id)) + + let res = [] + + const sameUserFunction = lodash.groupBy(users, (u) => u.function)[data.function] + const sameFunLength = sameUserFunction.length + + //if not enough related with same function, need to add users with same company size + if (sameFunLength <10) { + res = sameUserFunction + users = lodash.xor(users, sameUserFunction) + const sameUserSize = lodash.groupBy(users, (u) => u.company.size)[data.company.size] + const sameSizeLength = sameUserSize.length + + //still not enough related users, need to add users with same company sector + if (sameFunLength + sameSizeLength <10) { + res = lodash.concat(res, sameUserSize) + users = lodash.xor(users, sameUserSize) + const sameUserSector = lodash.groupBy(users, (u) => u.company.sector)[data.company.sector] + + //we keep up to 10 related users + res = lodash.concat(res, lodash.slice(sameUserSector, 0, 10-(sameFunLength + sameSizeLength ))) + + //too many related users with same company size, need to filter users to keep those with same company sector + } else { + if (sameFunLength + sameSizeLength > 10) { + const sameUserSizeSector = lodash.groupBy(sameUserSize, (u) => u.company.sector)[data.company.sector] + const sameSizeSectLength = sameUserSizeSector.length + + //not enough users with same company size + if (sameFunLength + sameSizeSectLength < 10) { + res = lodash.concat(res, sameUserSizeSector) + + //we complete res with users with same size to have 10 related users + res = lodash.concat(res, lodash.xor(sameUserSize, sameUserSizeSector).slice(0, 10-(sameFunLength + sameSizeSectLength))) + + //too many users with same company size and company sector : we keep only 10 related users + } else { + res = lodash.concat(res, lodash.slice(sameUserSizeSector, 0 , 10-sameFunLength)) + } + + //if sameFunLength + sameSizeLength == 10 + } else { + res = lodash.concat(res, sameUserSize) + } + } + + //too many related users with same function, need to filter users to keep those with same company size + } else { + if (sameFunLength > 10) { + const sameUserFunSize = lodash.groupBy(sameUserFunction, (u) => u.company.size)[data.company.size] + const sameFunSizeLength = sameUserFunSize.length + + //not enough users with same function and company size + if (sameFunSizeLength < 10) { + res = sameUserFunSize + + // we complete res with users with same function to have 10 related users + res = lodash.concat(res, lodash.xor(sameUserFunction, sameUserFunSize).slice(0, 10-sameFunSizeLength)) + + //too many users with same function and company size, need to filter users to keep those with same company sector + } else { + if (sameFunSizeLength > 10) { + const sameUserAll = lodash.groupBy(sameUserFunSize, (u) => u.company.sector)[data.company.sector] + const sameAllLength = sameUserAll.length + + //not enough users with same function, company size and company sector + if (sameAllLength < 10) { + res = sameUserAll + + //we complete res with users with same function and company size to have 10 related users + res = lodash.concat(res, lodash.xor(sameUserAll, sameUserFunSize).slice(0, 10-sameAllLength)) + + //we have 10 or more user with same function, company size and company sector : we only keep 10 + } else { + res = lodash.slice(sameUserAll, 0, 10) + } + + //we have exactly 10 users with same function and company size + } else { + res = sameUserFunSize + } + } + + //we have exactly 10 users with same function + } else { + res = sameUserFunction + } + } + return res + } + } } module.exports = { getRelated } \ No newline at end of file diff --git a/backend/web/server/plugins/cyberleague/schemas/UserSchema.js b/backend/web/server/plugins/cyberleague/schemas/UserSchema.js index b765db01c4..24cadf2000 100644 --- a/backend/web/server/plugins/cyberleague/schemas/UserSchema.js +++ b/backend/web/server/plugins/cyberleague/schemas/UserSchema.js @@ -156,6 +156,12 @@ const UserSchema = new Schema({ }], default: [] }, + related_users: { + type: [{ + type: Schema.Types.ObjectId, + ref: 'user' + }] + } }, {...schemaOptions, ...DISCRIMINATOR_KEY}) /* eslint-disable prefer-arrow-callback */