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

时间:2017-06-06 15:39:36

标签: java angularjs mongodb spring-data spring-mongodb

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

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

这里,进行分组操作的方法是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;
    }
}

REST 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前端调用该函数并在表格中显示该函数时,对于每个budgetCode,我在一个元素的数组中有taskCodes列表。例如,对于budgetCode [ "P231P00"],我可以拥有此任务代码列表:[ "61985" , "43606" , "60671" , "43602"]

好吧,我想拥有链接的taskCodes列表,而不是一个元素的数组,而是一个包含多个元素的数组: [ ["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。我更新了上面的报告类。最后,当我发出警报时: alert(读数[1] .listvalue [0]),我的结果如2630.所以,我成功地获得了特定budgetCode的第一个taskCode。

我明白这里重要的不是像我上面提到的那样[&#34; P231P00&#34;]这样的预算代码,我必须有一个列表:[ "61985" , "43606" , "60671" , "43602"]或{{1 }}。我必须有一个数组,而不是一个字符串。

当我显示[ ["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;
}

提前致谢

1 个答案:

答案 0 :(得分:1)

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

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

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

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"));