对字段进行分组操作并将喜欢的字段列表放入数组中

Grouping operation on a field and putting the list of the liked field in an array

我正在开发一个具有 AngularJS 前端和 Java 后端的 JHipster 项目。我在 MongoDb 数据库中使用 Spring 数据。

我对budgetCode字段进行了分组操作。因此,对于每个 budgetCode,我成功获得了所有链接的 taskCode 的列表。

这里,做分组操作的方法aggregateAllTask​​Codes:

存储层

public class ClarityResourceAffectationRepositoryImpl implements ClarityResourceAffectationRepositoryCustom {
    @Override
        public List<ClarityResourceAffectationReport> aggregateAllTaskCodes() {

            Aggregation aggregation = newAggregation(
                    group("budgetCode").addToSet("budgetCode").as("budgetCode").addToSet("taskCode").as("taskCode"),
                    sort(Sort.Direction.ASC, previousOperation(),"budgetCode"));

            AggregationResults groupResults = mongoTemplate.aggregate(aggregation, ClarityResourceAffectation.class,
                    ClarityResourceAffectationReport.class);
            List<ClarityResourceAffectationReport> clarityResourceAffectationReports = groupResults.getMappedResults();

            return clarityResourceAffectationReports;
        }
    }

服务层

public class ClarityResourceAffectationServiceImpl implements ClarityResourceAffectationService{
    @Override
    public List<ClarityResourceAffectationReport> aggregateAllTaskCodes() {
        log.debug("Request to aggregateByCodeBudgetForCodeTache : {}");
        List<ClarityResourceAffectationReport> result = clarityResourceAffectationRepository
                .aggregateAllTaskCodes();

        return result;
    }
}

休息API层

public class ClarityResourceAffectationResource {
    @GetMapping("/clarity-resource-affectations/list-task-codes")
    @Timed
    public ResponseEntity<List<ClarityResourceAffectationReport>> aggregateTabAllTaskCodes() {
        log.debug("REST request to get aggregateTabAllTaskCodes : {}");
        List<ClarityResourceAffectationReport> result = clarityResourceAffectationService.aggregateAllTaskCodes();
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
}

ClarityResourceAffectation

@Document(collection = "clarity_resource_affectation")
public class ClarityResourceAffectation implements Serializable {

    @Id
    private String id;

    @Field("budget_code")
    private String budgetCode;

    @Field("task_code")
    private String taskCode;

    public String getBudgetCode() {
        return budgetCode;
    }

    public void setBudgetCode(String budgetCode) {
        this.budgetCode = budgetCode;
    }

    public String getTaskCode() {
        return taskCode;
    }

    public void setTaskCode(String taskCode) {
        this.taskCode = taskCode;
    }
}

ClarityResourceAffectationReport

public class ClarityResourceAffectationReport implements Serializable {

    private static final long serialVersionUID = 1L;

    private String budgetCode;
    private String taskCode;
    private String listTaskCode;

    public String getBudgetCode() {
        return budgetCode;
    }

    public void setBudgetCode(String budgetCode) {
        this.budgetCode = budgetCode;
    }

    public String getTaskCode() {
        return taskCode;
    }

    public void setTaskCode(String taskCode) {
        this.taskCode = taskCode;
    }
    public String[] getListTaskCode() {
        return listTaskCode;
    }

    public void setListTaskCode(String[] listTaskCode) {
        this.listTaskCode = listTaskCode;
    }
}

清晰度资源-affectation.service.js

(function() {
    'use strict';
    angular
        .module('dashboardApp')
        .factory('ClarityResourceAffectation', ClarityResourceAffectation);

    ClarityResourceAffectation.$inject = ['$resource'];

    function ClarityResourceAffectation ($resource) {
        var resourceUrl =  'clarity/' + 'api/clarity-resource-affectations/:id';

        return $resource(resourceUrl, {}, {
            'query': { method: 'GET', isArray: true},
            'aggregateAllTaskCodes': {
                method: 'GET',
                isArray: true,
                url: 'clarity/api/clarity-resource-affectations/list-task-codes'
            }
        });
    }
})();

当我在 AngularJS 前端调用该函数并将其显示在 table 上时,对于每个 budgetCode,我都将任务代码列表放在一个元素数组中。例如,对于 budgetCode [ "P231P00"] 我可以有这个 taskCodes 列表:[ "61985" , "43606" , "60671" , "43602"]

好吧,我想要链接任务代码的列表,不是在一个元素的数组中,而是在多个元素的数组中,如下所示: [ ["61985"] , ["43606"] , ["60671"] , ["43602"] ]

为了做到这一点,我必须更改我的代码中的哪些内容?

仅供参考,我的 javascript 基于聚合函数创建数组的代码:

清晰度-资源影响-列表-任务-codes.controller.js

(function() {
    'use strict';

    angular
        .module('dashboardApp')
        .controller('ClarityResourceAffectationTableauBordNbCollaborateursController', ClarityResourceAffectationTableauBordNbCollaborateursController);

    ClarityResourceAffectationTableauBordNbCollaborateursController.$inject = ['$timeout', '$scope', '$stateParams', 'DataUtils', 'ClarityResourceAffectation'];

    function ClarityResourceAffectationTableauBordNbCollaborateursController ($timeout, $scope, $stateParams, DataUtils, ClarityResourceAffectation) {
        var vm = this;

        //Call of the function    
        allTaskCodes()

        function allTaskCodes()
        {
            ClarityResourceAffectation.aggregateAllTaskCodes(function(readings) {

                var dataAllTaskCodes;
                dataAllTaskCodes = [];

                alert(readings);

                readings.forEach(function (item) {
                    dataAllTaskCodes.push({
                        label: item.budgetCode,
                        value: item.taskCode,
                        listvalue: item.listTaskCode
                    });
                });

                vm.dataAllTaskCodes = dataAllTaskCodes;
            });
        }
    }
})();

临时解决方案: 实际上,我通过完成我在服务层创建的方法找到了一个临时解决方案:

@Override
public List<ClarityResourceAffectationReport> aggregateAllTaskCodes() {
    log.debug("Request to aggregateAllTaskCodes : {}");
    List<ClarityResourceAffectationReport> result = clarityResourceAffectationRepository
            .aggregateAllTaskCodes();

    Iterator<ClarityResourceAffectationReport> iterator = result.iterator();
    while (iterator.hasNext())
    {
        ClarityResourceAffectationReport resAffectationReport = iterator.next();

        String taskCodes = resAffectationReport.getTaskCode();

        //Delete all exept letters, numbers and comma
        taskCodes = taskCodes.replaceAll("[^a-zA-Z0-9,]","");

        String[] listTaskCodes = taskCodes.split(",");

        resAffectationReport.setListTaskCodes(listTaskCodes);
    }

    return result;
}

此外,我在 ClarityResourceAffectationReport 中添加了一个附加字段,即 listTaskCode。我更新了上面的报告 class。最后,当我发出警报时: alert(readings[1].listvalue[0]),我得到的结果是2630。所以,我成功获得了特定budgetCode的第一个taskCode。

我明白这里重要的不是我上面所说的像 ["P231P00"] 这样的预算代码,我必须有一个像这样的列表:[ "61985" , "43606" , "60671" , "43602"][ ["61985"] , ["43606"] , ["60671"] , ["43602"] ].我只需要一个数组,而不是一个字符串。

当我显示 alert(readings[1].listvalue) 时,我有 ["2630","61297","61296","61299"],这显然是一个数组,因为我可以通过调用 alert(readings[1].listvalue[0])alert(readings[1].listvalue[1]] 等来访问每个元素。 ..

我试过你建议的方法

但是,还是不行。在这里,我的存储库代码:

@Override
public List<ClarityResourceAffectationReport> aggregateAllTaskCode() {

    AggregationOperation project = new AggregationOperation() {
        @Override
        public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
            return new BasicDBObject("$project", new BasicDBObject("budgetCode", "$budget_code").append("taskCode", Arrays.asList("$task_code")));
        }
    };

    Aggregation aggregation = newAggregation(project,
            group("budgetCode").addToSet("budgetCode").as("budgetCode").addToSet("taskCode").as("taskCode"),
            sort(Sort.Direction.ASC, previousOperation(),"budgetCode"));


    AggregationResults groupResults = mongoTemplate.aggregate(aggregation, ClarityResourceAffectation.class,
            ClarityResourceAffectationReport.class);
    List<ClarityResourceAffectationReport> clarityResourceAffectationReports = groupResults.getMappedResults();

    log.debug("clarityResourceAffectationReports.size() => " + clarityResourceAffectationReports.size());
    log.debug("aggregation.toString() => " + aggregation.toString());

    return clarityResourceAffectationReports;
}

在这里,您可以找到日志:

clarityResourceAffectationReports.size() => 1
aggregation.toString() => {"aggregate" : "__collection__" , "pipeline" : [ { "$project" : { "budgetCode" : "$budget_code" , "taskCode" : [ "$task_code"]}} , { "$group" : { "_id" : "$budgetCode" , "budgetCode" : { "$addToSet" : "$budgetCode"} , "taskCode" : { "$addToSet" : "$taskCode"}}} , { "$sort" : { "_id" : 1 , "budgetCode" : 1}}]}

提前致谢

您需要使用$projecttaskCodes值更改为$group之前的单值数组。

我在 api 中没有看到任何钩子来解决这个问题。

您可以使用 AggregationOperation 使用 mongodb (BasicDBObject) 种类型创建 $project 阶段。

AggregationOperation project = new AggregationOperation() {
       @Override
       public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
          return new BasicDBObject("$project", new BasicDBObject("budgetCode", 1).append("taskCode", Arrays.asList("$taskCode")));
    } 
};

类似于

Aggregation aggregation = newAggregation(project,
                    group("budgetCode").addToSet("budgetCode").as("budgetCode").addToSet("taskCode").as("taskCode"),
                    sort(Sort.Direction.ASC, previousOperation(), "budgetCode"));

使用 lambda

 Aggregation aggregation = newAggregation(
                aggregationOperationContext -> new BasicDBObject("$project", new BasicDBObject("budgetCode", 1).append("taskCode", Arrays.asList("$taskCode"))),
                group("budgetCode").addToSet("budgetCode").as("budgetCode").addToSet("taskCode").as("taskCode"),
                sort(Sort.Direction.ASC, previousOperation(), "budgetCode"));