Весна-Монго группировка по агрегации. Дальнейшее объединение и отображение - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь выполнить групповую операцию для коллекции Mongo. Это использует Spring / Java.

Вот как выглядит документ в коллекции:

{ 
   "_id":"5dae0f45f149e031e86215af",
   "users":[ 
      { 
         "userName":"abc345",
         "firstName":"Bob",
         "lastName":"Smith"
      },
      { 
         "userName":"xyz123",
         "firstName":"Jim",
         "lastName":"Miller"
      }
   ],
   "categoryId":"5d4855f15e18c75328651269",
   "description":"Default Item for compliance item",
   "startDate":"2018-04-28T00:00:00.000Z",
   "endDate":"2018-05-13T00:00:00.000Z",
   "status":"Incomplete",
   "wippPadId":"1048",
   "ownerName":"CNC",
   "ownerTypeId":"5d433ceb5e18c75328651265",
   "_class":"com.apc.its.services.cnc.model.data.ComplianceItem"
}

Соответствующий Java-объект выглядит следующим образом:

class ComplianceItem {

    @Id
    String id;

    List<User> users;
    String categoryId;
    String description;
    Date startDate;
    Date endDate;
    String status;
    Long wippPadId;
    String ownerName;
    String ownerTypeId;
}

Я группирую по wippPadId и status . Вот как выглядит операция группировки в коде Java:

List<GroupingByPadAndStatus> getComplianceItemCountsByUserGroupedByPadAndStatus(String userName) {
    MatchOperation matchOperation = matchByUser(userName);
    GroupOperation groupOperation = groupByPadAndStatus();
    ProjectionOperation projectionOperation = projectByPadAndStatus();

    List<GroupingByPadAndStatus> itemCountsByPadAndStatus = mongoTemplate.aggregate(Aggregation.newAggregation(
            matchOperation,
            groupOperation,
            projectionOperation
    ), ComplianceItem.class, GroupingByPadAndStatus.class).getMappedResults();

    return itemCountsByPadAndStatus;
}

MatchOperation matchByUser(String userName) {
    Criteria padCriteria = where("users.userName").is(userName);
    return match(padCriteria);
}

GroupOperation groupByPadAndStatus() {
    return group("wippPadId", "status")
            .addToSet("wippPadId").as("wippPadId")
            .addToSet("status").as("status")
            .count().as("count");
}

ProjectionOperation projectByPadAndStatus() {
    return project("value", "status", "wippPadId");
}

В результате получается список этих объектов:

class GroupingByPadAndStatus {
    Long wippPadId;
    Long count;
    String status;
}

Таким образом, полученный json выглядит примерно так:

[
    {
        "wippPadId": 1024,
        "status": "Incomplete",
        "count": 0
    },
    {
        "wippPadId": 1024,
        "status": "Complete",
        "count": 1
    },  
    {
        "wippPadId": 1024,
        "status": "In Progress",
        "count": 3
    },
    {
        "wippPadId": 1025,
        "status": "Incomplete",
        "count": 1
    },
    {
        "wippPadId": 1025,
        "status": "Complete",
        "count": 0
    },  
    {
        "wippPadId": 1025,
        "status": "In Progress",
        "count": 0
    }
]

Вместо этого я хочу получить список этих объектов:

class GroupingByPadAndStatus {
    Long wippPadId;
    List<GroupingByPadAndStatus> groupingByPadAndStatusList;
}

Итак, мне нужна карта wippPadId -> GroupingByPadAndStatus. Что сделало бы получившийся json более похожим на это:

[
    {
        "wippPadId": 1024,
        "groupingByPadAndStatusList": [
            {
                "status": "Incomplete",
                "count": 0
            },
            {
                "status": "Complete",
                "count": 1
            },
            {
                "status": "In Progress",
                "count": 3
            }
        ]
    },
    {
        "wippPadId": 1025,
        "groupingByPadAndStatusList": [
            {
                "status": "Incomplete",
                "count": 1
            },
            {
                "status": "Complete",
                "count": 0
            },
            {
                "status": "In Progress",
                "count": 0
            }
        ]
    }
]

Любой способ сделать это с помощью агрегатов Spring Mongo. После этого я попытался обработать результаты, но для большого количества записей это происходит медленно. Спасибо

...