MongoDb Group BY MAX日期并从此文档中获取字段

时间:2019-10-23 14:06:59

标签: mongodb mongodb-query aggregation-framework

瞧瞧我这个无能的呵呵。我不知道该怎么办。 有很多assetState 1..n我想进行汇总以按资产获取最后一个资产状态组。

Mongo集合:assetState

[
{
    "lsd" : {
     "$id" : ObjectId("lucas")
    },
    "stateDate" : ISODate("2018-09-10T16:26:44.501Z"),
    "assetId" : ObjectId("5b96b7645f2b3c0101520s60")
},
{
    "lsd" : {
     "$id" : ObjectId("denner")
    },
    "stateDate" : ISODate("2018-09-10T17:26:44.501Z"),
    "assetId" : ObjectId("5b96b7645f2b3c0101520s60")
},
{
    "lsd" : {
     "$id" : ObjectId("denner")
    },
    "stateDate" : ISODate("2018-09-10T18:26:44.501Z"),
    "assetId" : ObjectId("5b96b7645f2a8c0001530f61")
},
{
    "lsd" : {
      "$id" : ObjectId("lermen")
        }
    },
    "stateDate" : ISODate("2018-09-10T20:26:44.501Z"),
    "assetId" : ObjectId("5b96b7645f2a8c0001530f61")
},
{
    "lsd" : {
      "$id" : ObjectId("floripa")
    },
    "stateDate" : ISODate("2018-09-10T19:26:44.501Z"),
    "assetId" : ObjectId("5b96b7645f2a8c0001530f61")
}
]

我想获取最大的“ stateDate”,所以我需要从同一行(文档)获取LSD。

预期结果:

{
    "lsd" : {
      "$id" : ObjectId("lermen")
    },
    "stateDate" : ISODate("2018-09-10T20:26:44.501Z")
}

我试图做:

db.getCollection('assetState').aggregate([
{
        $group: {
            "_id": {"assetId": "$assetId"},
            "stateDate": {
                "$max": "$stateDate"
            },
            "lsd":  {$last: "$lsd"} // I tried change $max to $min and $last it din't work :(

        }
]);

结果:

{
    "lsd" : {
      "$id" : ObjectId("floripa")
    },
    "stateDate" : ISODate("2018-09-10T20:26:44.501Z")
}

非常感谢

4 个答案:

答案 0 :(得分:0)

尝试此查询

db.getCollection('assetState').aggregate([
{$sort:{"stateDate":-1}},
]).limit(1)

答案 1 :(得分:0)

您可以$sort降到$group之前,并使用$arrayElemAt来获得每个组的第一项

db.getCollection('assetState').aggregate([
{ $sort: { stateDate: -1 } },
{ $group: { _id: { "assetId" : "$assetId" }, 
    states: { $push: "$$ROOT" }
    }
},
{ $project: { "last_asset": { $arrayElemAt: [ "$states", 0 ] }, _id:0  } },
])

结果:

/* 1 */
{
    "last_asset" : {
        "_id" : ObjectId("5db2b34fa1b70230bba9c4d9"),
        "lsd" : "denner",
        "stateDate" : ISODate("2018-09-10T17:26:44.501Z"),
        "assetId" : "5b96b7645f2b3c0101520s60"
    }
}

/* 2 */
{
    "last_asset" : {
        "_id" : ObjectId("5db2b34fa1b70230bba9c4db"),
        "lsd" : "lermen",
        "stateDate" : ISODate("2018-09-10T20:26:44.501Z"),
        "assetId" : "5b96b7645f2a8c0001530f61"
    }
}

答案 2 :(得分:0)

答案 3 :(得分:0)

我有这个按阶段分组:

public Long register(UserDTO userDTO) throws BusinessException{

    if (Objects.isNull(userDTO)) {
        throw new BusinessException(401, "Body null !");
    }

    if (Objects.isNull(userDTO.getEmail())) {
        throw new BusinessException(400, "Email cannot be null ! ");
    }

    if (Objects.isNull(userDTO.getPassword())) {
        throw new BusinessException(400, "Password cannot be null !");
    }

    if (Objects.isNull(userDTO.getFirstName())){
        throw new BusinessException(400, "First Name cannot be null !");

    }

    if (Objects.isNull(userDTO.getLastName())){
        throw new BusinessException(400, "Last Name cannot be null !");
    }

因此对 2 个字段进行分组,我使用最大值来获取 timeOfEvent(这是一个日期)的最大值