【问题标题】:Grouping operation on a field and putting the list of the liked field in an array对字段进行分组操作并将喜欢的字段列表放入数组中
【发布时间】:2017-06-06 15:39:35
【问题描述】:

我正在开发一个带有 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;
    }
}

clarity-resource-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 前端调用函数并将其显示在表格上时,对于每个预算代码,我都有一个元素数组中的任务代码列表。例如,对于预算代码[ "P231P00"],我可以拥有以下任务代码列表:[ "61985" , "43606" , "60671" , "43602"]

好吧,我想要链接任务代码的列表,而不是在一个元素的数组中,而是在一个像这样的几个元素的数组中: [ ["61985"] , ["43606"] , ["60671"] , ["43602"] ]

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

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

clarity-resource-affectation-list-task-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;
            });
        }
    }
})();

临时解决方案: 其实我通过完成我在Service层创建的方法找到了一个临时的解决方案:

@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(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}}]}

提前致谢

【问题讨论】:

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


    【解决方案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"));
    

    【讨论】:

    • 我把前端和后端之间的链接和更多细节。我会尝试更多的东西,然后再问你,因为我没有成功拥有我想要的东西。我向您提供了有关我的代码的更多详细信息。
    • 您遇到什么错误并尝试将ClarityResourceAffectationReport pojo 添加到帖子中?
    • 我添加了 ClarityResourceAffectationReport。我试过你的代码。调用函数后:alert(readings) 和 alert(readings[0]) 给了我[object Object]。此外,读数[0].budgetCode 给了我:[ ]。某些地方必须有所改变。
    • 感谢您的信息。您必须将您的字段更新为数组,以便 spring 正确映射它。 private String[] budgetCode; private String[][] taskCode;。也调整 setter 和 getter。
    • 是的,我更新了ClarityResourceAffectationReport 并将private String[] budgetCode; private String[][] taskCode 与相应的getter 和setter 放在一起。但是,当我做alert(readings)alert(readings[0]) 时,我有[object Object]alert(readings.length); 给了我1。所以,出了点问题。我继续调查。无论如何,我通过完成 Service layer 方法添加了一个替代解决方案。我更新了帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    相关资源
    最近更新 更多