【问题标题】:How to trim MongoDB aggregate result's one field如何修剪 MongoDB 聚合结果的一个字段
【发布时间】:2017-07-05 00:22:59
【问题描述】:

这是我在数据库中存储的数据结构

{
    "_id" : ObjectId("58a4e451c164f95c98e96235"),
    "_class" : "com.contix.log.parser.log.Log",
    "vin" : "6",
    "esn" : "c",
    "volt" : 11.32,
    "internVolt" : 4.14,
    "temp" : 39.49,
    "timestamp" : NumberLong("1483375743285")
}

我想要做的是根据 vin 和 esn 字符串获取最新的 10 个独特的 volt、internVolt、temp。还需要最新的时间戳。然后我尝试使用 mongo 聚合方式来获得正确的结果。

db.log.aggregate({$sort:{timestamp:-1}},{$group:{_id : {esn:"$esn",vin:"$vin"},firstTimestamp:{$first:"$timestamp"},volts:{$addToSet:"$volt"}}},{$limit:5})

但这是我的结果看起来像

{“_id”:{“esn”:“b”,“vin”:“2”},“firstTimestamp”: NumberLong("1485852368147"), "伏特" : [ 11.95, 10.08, 10.77, 10.47, 11.41,10.36,10.96,10.75,10.39,10.53,10.1,10.22,11.16,10.11,11.87,11.33,11.82,11.78,10.25,11.86,10.5,10.41,11.3,11.31,11.97,10.64,11.57,10.93,10.02, 10.68,10.9,11.53,10.46,11.42,11.73,11.32,10.19,10.51,11.35,11.28,10.65,10.21,11.18,10.91,11.43,10.52,11.34,11.1,1099,10.61,10.28,1097,10.3,1031, 11.81,11.8,10.42,11.51,10.72,11.39,10.69,11.27,11.11,10.15,10.78,10.58,11.49,10.94,11.64,10.32,11.63,10.03,10.81,11.83,10.82,11.84,10.79,10.66,11.21, 10.24、11.75、11.2] }

还有其他 4 个类似的东西。

我不知道是否有任何方法可以修剪 $volts 这种数据 int 组管道。 $limit 或 $skip 操作似乎用于整个文档。

我的梦想结果应该如下所示。

{“_id”:{“esn”:“b”,“vin”:“2”},“firstTimestamp”: NumberLong("1485852368147"), "volts" : [ 10.81, 11.83, 10.82, 11.84, 10.79, 10.66, 11.21, 10.24, 11.75, 11.2 ], "innerVolts":[...], "temp":[.. .] }

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    如果您需要修剪结果,您可以使用投影并执行以下操作:

    db.log.aggregate([
             {$sort:{timestamp:-1}},
             {$group:{
                      _id : {esn:"$esn",vin:"$vin"},
                     firstTimestamp:{$first:"$timestamp"},
                     volts:{$addToSet:"$volt"},
                     innerVolts:{$addToSet:"$innerVolt"},
                     temp:{$addToSet:"$temp"}                     
              }},
              { $project: {
                   _id:1,
                   firstTimestamp:1,
                   volts: {$slice : ["$volts",10]},
                   innerVolts: {$slice : ["$innerVolts",10]}, 
                   temp: {$slice:["$temp",10]}
               }}])
    

    希望我的回答对您有所帮助。

    【讨论】:

    • 我知道这一点。我只想得到最后十个元素的伏特。
    • 我想我遇到了你的问题。请检查我的版本。
    • 有没有可能我切片后 10 个元素而不是前 10 个?因为我发现最后十个元素是最新的 10 个。我认为 addToSet 可能会保留一个链接列表。
    • 你知道如何将这个项目操作映射到Spring Mongo模板吗?当我使用项目(字段...)时,我输入项目(“id”,“firstTimestamp”,“volts”)。但似乎我应该将 $slice 添加到伏特中......我没有更多的配额来问另一个问题......
    • 对不起,我从未使用过 Spring Mongo。通常我使用nodejs。
    【解决方案2】:

    您可以使用$slice 修饰符将数组修剪为最新的 N 项。

    【讨论】:

    • 谢谢,我已经弄清楚了。但是当我将查询映射到 JAVA 时,我遇到了一个新问题,即 ProjectionOperation 没有切片这种方法。所以我不知道你是否知道这个问题。我没有配额可以问更多问题--生活如此艰难......
    • MongoDB 确实支持投影运算符 $slice。 (docs.mongodb.com/manual/reference/operator/projection/slice)。您使用的 JAVA 库可能有问题。
    猜你喜欢
    • 2020-08-19
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 2023-02-11
    • 1970-01-01
    相关资源
    最近更新 更多