Среднее значение в $ lookup из нескольких полей

#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']
                        }
                    }
                }
            ]);