#node.js #typescript #express #mongoose #aggregation-framework
#node.js #машинописный текст #экспресс #мангуст #агрегация-фреймворк
Вопрос:
У меня есть две схемы
export interface IRating extends Document {
user?: Schema.Types.ObjectId;
company?: Schema.Types.ObjectId;
email: string;
userRole: string;
userEmploymentStatus?: string;
userDepartment: string;
headline: string;
companyCulture: number;
companyInternalCommunication: number;
companyTeamwork: number;
companyWorkLifeBalance: number;
companySupportFromTheManagement: number;
companyFreedomOfIndependentWork: number;
diversityInclusiveOrDiverse: number;
diversityGenderEquality: number;
diversityAttitudeTowardsOderColleagues: number;
workEnvOffice: number;
workEnvFriendliness: number;
workEnvHandicappedAccess: number;
workEnvSafety: number;
careerCompensationForWork: number;
careerJobSecurity: number;
careerCompanyImage: number;
careerDevelopment: number;
careerChallengingWork: number;
suggestionsForImprovement: string;
likedStuffAboutCompany: string;
dislikedStuffAboutCompany: string;
recommendation: boolean;
benefits: string[];}
export interface ICompany extends Document {
creatorId?: Schema.Types.ObjectId;
ratings?: [{ type: Schema.Types.ObjectId }];
creatorEmail: string;
name: string;
city: string;
country: string;
industryType: string;
deletedAt?: Date | null;
}
Я хочу добиться того, чтобы все компании получили средний балл своих рейтингов. Как вы можете видеть, у одной компании может быть больше оценок.
В настоящее время у меня есть этот фрагмент
Company.aggregate([
{
$lookup:
{
from: "ratings",
localField: "ratings",
foreignField: "_id",
as: "ratings"
},
}
]);
Но, конечно, это возвращает только СОЕДИНЕНИЕ для двух коллекций. Мне нужно получить среднее значение по всем поданным номерам в коллекции рейтингов.
РЕДАКТИРОВАТЬ После небольшого исследования мне удалось написать это.
Company.aggregate([
{
$lookup:
{
from: "ratings",
localField: "ratings",
foreignField: "_id",
as: "ratings"
},
},
{
$addFields: {
averagePerDocument: {
$map:
{
input: "$ratings",
as: "rating",
in: {$avg:["$$rating.companyCulture","$$rating.companyInternalCommunication",
"$$rating.companyTeamwork", "$$rating.companyWorkLifeBalance",
"$$rating.companySupportFromTheManagement", "$$rating.companyFreedomOfIndependentWork",
"$$rating.diversityInclusiveOrDiverse", "$$rating.diversityGenderEquality",
"$$rating.diversityAttitudeTowardsOderColleagues", "$$rating.workEnvOffice",
"$$rating.workEnvFriendliness", "$$rating.workEnvHandicappedAccess", "$$rating.workEnvSafety",
"$$rating.careerCompensationForWork", "$$rating.careerJobSecurity", "$$rating.careerCompanyImage",
"$$rating.careerDevelopment", "$$rating.careerChallengingWork"]}
}
}
}
}
]);
Это возвращает мне это. (Обратите внимание, что я не вставил весь JSON)
"averagePerDocument": [
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
2.9444444444444446,
1,
5
]
Теперь мне нужно, чтобы в одном поле отображалось только среднее значение из этих значений.
Обновите еще раз. Извините, я думаю, что я могу думать лучше, когда рядом со мной есть пиво. Я просто использовал проекцию
Company.aggregate([
{
$lookup:
{
from: "ratings",
localField: "ratings",
foreignField: "_id",
as: "ratings"
},
},
{
$addFields: {
averagePerDocument: {
$map:
{
input: "$ratings",
as: "rating",
in: {$avg:["$$rating.companyCulture","$$rating.companyInternalCommunication",
"$$rating.companyTeamwork", "$$rating.companyWorkLifeBalance",
"$$rating.companySupportFromTheManagement", "$$rating.companyFreedomOfIndependentWork",
"$$rating.diversityInclusiveOrDiverse", "$$rating.diversityGenderEquality",
"$$rating.diversityAttitudeTowardsOderColleagues", "$$rating.workEnvOffice",
"$$rating.workEnvFriendliness", "$$rating.workEnvHandicappedAccess", "$$rating.workEnvSafety",
"$$rating.careerCompensationForWork", "$$rating.careerJobSecurity", "$$rating.careerCompanyImage",
"$$rating.careerDevelopment", "$$rating.careerChallengingWork"]}
}
}
}
},
{
$project: {
_id:1,
name:1,
test: {
$avg:['$averagePerDocument']
}
}
}
]);