예제 #1
0
    async def __do_get_report_data(self):
        subject_dimension_list = await SubjectDimension.aggregate([
            MatchStage({'parent_cid': None}),
            SortStage([('ordered', ASC)]),
            LookupStage(SubjectDimension, 'cid', 'parent_cid', 'sub_list')
        ]).to_list(None)

        match_dict = {}
        search_arguments = {}

        # 地方科协不会开放此权限,因此导出全部省份数据
        # m_province_code_list, m_city_code_list, _ = await do_different_administrative_division2(
        #     self.current_user.manage_region_code_list)
        # if m_province_code_list:
        #     match_dict['province_code'] = {'$in': m_province_code_list}
        # if m_city_code_list:
        #     match_dict['city_code'] = {'$in': m_city_code_list}

        # 维度信息
        dimension_dict = {}
        for dimension in subject_dimension_list:
            t_dimension = self.get_argument(dimension.cid, '')
            if t_dimension:
                dimension_dict['%s' % dimension.cid] = t_dimension
            search_arguments[dimension.cid] = t_dimension

        # 默认只显示,状态启用,并且不是基准测试或毕业测试的题目
        match_dimension = {'$and': [
            {'status': STATUS_SUBJECT_ACTIVE},
            {'category_use': {
                '$nin': [CATEGORY_SUBJECT_BENCHMARK, CATEGORY_SUBJECT_GRADUATION]}}
        ]}
        if dimension_dict:
            match_dimension['$and'].extend([{'dimension_dict.%s' % k: v} for k, v in dimension_dict.items()])

        subject_cid_list = await Subject.distinct('cid', match_dimension)
        if subject_cid_list:
            match_dict['subject_cid'] = {'$in': subject_cid_list}

        query_params = {}
        s_province = self.get_argument('province', '')
        if s_province:
            query_params['province_code'] = s_province
        search_arguments['province'] = s_province

        s_city = self.get_argument('city', '')
        if s_city:
            query_params['city_code'] = s_city
        search_arguments['city'] = s_city

        s_age_group = self.get_argument('age_group', '')
        if s_age_group:
            query_params['age_group'] = int(s_age_group)
        search_arguments['age_group'] = s_age_group

        s_gender = self.get_argument('gender', '')
        if s_gender:
            query_params['gender'] = int(s_gender)
        search_arguments['gender'] = s_gender

        s_education = self.get_argument('education', '')
        if s_education:
            query_params['education'] = int(s_education)
        search_arguments['education'] = s_education

        manage_stage = MatchStage(match_dict)
        query_stage = MatchStage(query_params)
        group_stage = GroupStage('subject_cid', t_total={'$sum': '$total'}, t_correct={'$sum': '$correct'})
        project_stage = ProjectStage(
            total='$t_total', correct='$t_correct',
            percent={
                '$cond': {
                    'if': {'$eq': ['$t_total', 0]},
                    'then': 0,
                    'else': {
                        '$divide': ['$t_correct', '$t_total']
                    }
                }
            }
        )

        s_lookup_stage = LookupStage(Subject, '_id', 'cid', 'subject_list')
        so_lookup_stage = LookupStage(SubjectOption, '_id', 'subject_cid', 'subject_option_list')

        not_null_match = MatchStage({
            'subject_list': {'$ne': []},
            'subject_option_list': {'$ne': []}
        })

        final_project = ProjectStage(**{
            'custom_code': {'$arrayElemAt': ['$subject_list.custom_code', 0]},
            'code': {'$arrayElemAt': ['$subject_list.code', 0]},
            'title': {'$arrayElemAt': ['$subject_list.title', 0]},
            'subject_list': '$subject_list',
            'subject_option_list': '$subject_option_list',
            'dimension': {'$arrayElemAt': ['$subject_list.dimension_dict', 0]},
            'total': '$total',
            'correct': '$correct',
            'percent': '$percent'
        })

        sort_list = []
        sort = self.get_argument('sort')
        if sort:
            sort = int(sort)
        else:
            sort = 1

        search_arguments['sort'] = sort
        if sort == 1:
            sort_list.append('-percent')
        elif sort == 2:
            sort_list.append('percent')
        sort_list.append('-total')

        return MemberSubjectStatistics.aggregate([
            manage_stage, query_stage, group_stage, project_stage, s_lookup_stage, so_lookup_stage, not_null_match,
            final_project
        ])