MongoDb,查询最后一个,并分组

MongoDb, query the last, and group by

我在处理 MongoDb 时遇到了麻烦。

我需要:

我知道我们可以将 $last 与 mongodb 一起使用,但我完全不知道如何进行。

我试过了:

db.collection.aggregate(
   [
     {
       $group:
         {
           _id: "$zone._id",
           lastRegistered: { $last: "$_id" }
         }
     }
   ]
)

但它似乎没有给我我需要的东西

编辑示例

据此三:

  { _id: 55d5a01f9f58d2cc0eb79f5d,
    controlDate: Thu Aug 20 2015 11:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
    zone:
     { _id: 55cb5bb42d191d2022c5c266,
       zoneName: 'Syphon 1',
     },
    actif: true 
    },



  { _id: 55d59f129f58d2cc0eb79f5c,
    controlDate: Fri Aug 21 2015 07:34:12 GMT+0200 (Paris, Madrid (heure d’été)),
    zone:
     { _id: 55cb5bb42d191d2022c5c266,
       zoneName: 'Syphon 1',
     },
    actif: true 
    }



  { _id: 55d5a01f9f58d2cc0eb79f5e,
        controlDate: Fri Aug 20 2015 08:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
        zone:
         { _id: 55cb5bb42d191d2022c5c278,
           zoneName: 'Other zone',
         },
        actif: true 
        },

我需要得到:

  { _id: 55d59f129f58d2cc0eb79f5c,
    controlDate: Fri Aug 21 2015 07:34:12 GMT+0200 (Paris, Madrid (heure d’été)),
    zone:
     { _id: 55cb5bb42d191d2022c5c266,
       zoneName: 'Syphon 1',
     },
    actif: true 
    }



  { _id: 55d5a01f9f58d2cc0eb79f5e,
        controlDate: Fri Aug 20 2015 08:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
        zone:
         { _id: 55cb5bb42d191d2022c5c278,
           zoneName: 'Other zone',
         },
        actif: true 
        },

这意味着:我需要获取按区域 _id 分组的此集合的最后一个(按 ID 或日期,没关系)。 (2 行,因为我有一个区域的 2 个数据集(我只需要最后一个),我需要另一个区域的最后一个(只有 1 行所以..))

你明白我的意思吗?

$last 为您提供由您的分组处理的最后一个文档的值。您无法预测文档的处理顺序,除非您对文档进行排序。所以你没有得到你期望的结果。

尝试在 $group 阶段之前添加一个 $sort 阶段,以按日期升序获取文档:

db.collection.aggregate(
   [
     { $sort: {
           "control_date":1
       }
     },
     {
       $group:
         {
           _id: "$zone._id",
           lastRegistered: { $last: "$_id" },
           zoneName:"$zone.zoneName",
           control_id:"$_id",
           actif:"$actif",
         }
     }
   ]
)

您始终可以使用 $$ROOT 来 return 分组边界上的整个文档:

db.collection.aggregate([
    { "$group": { 
        "_id": "$zone._id",
        "doc": { "$last": "$$ROOT" }
    }}
 ])

或者使用直接排序控制而不是自然顺序:

db.collection.aggregate([
    { "$sort": { "_id": 1 } },
    { "$group": { 
        "_id": "$zone._id",
        "doc": { "$last": "$$ROOT" }
    }}
  ])

但请注意,$group 管道不保证保留文档顺序,因此如果您需要,那么您再次 $sort

db.collection.aggregate([
    { "$sort": { "_id": 1 } },
    { "$group": { 
        "_id": "$zone._id",
        "doc": { "$last": "$$ROOT" }
    }},
    { "$sort": { "doc._id": 1 } }
 ])

在所有情况下,更改为 $$ROOT 只是声明 $last explicitly for each field you want from the document. By contrast the $max 运算符仅适用于指定字段,因此当您需要来自分组边界的文档时,这通常对您没有用正如 $last 所做的那样。


考虑那里的 "last" 示例并从您的示例中删除适当的数据然后我得到:

{
    "_id" : "55cb5bb42d191d2022c5c266",
    "doc" : {
            "_id" : "55d5a01f9f58d2cc0eb79f5d",
            "zone" : {
                    "_id" : "55cb5bb42d191d2022c5c266",
                    "zoneName" : "Syphon 1"
            },
            "actif" : true
    }
},
{
    "_id" : "55cb5bb42d191d2022c5c278",
    "doc" : {
            "_id" : "55d5a01f9f58d2cc0eb79f5e",
            "zone" : {
                    "_id" : "55cb5bb42d191d2022c5c278",
                    "zoneName" : "Other zone"
            },
            "actif" : true
    }
}

修改后的输入是这样的:

{
    "_id" : "55d5a01f9f58d2cc0eb79f5d",
    "zone" : {
            "_id" : "55cb5bb42d191d2022c5c266",
            "zoneName" : "Syphon 1"
    },
    "actif" : true
},
{
    "_id" : "55d59f129f58d2cc0eb79f5c",
    "zone" : {
            "_id" : "55cb5bb42d191d2022c5c266",
            "zoneName" : "Syphon 1"
    },
    "actif" : true
},
{
    "_id" : "55d5a01f9f58d2cc0eb79f5e",
    "zone" : {
            "_id" : "55cb5bb42d191d2022c5c278",
            "zoneName" : "Other zone"
    },
    "actif" : true
}

不关心正确的 ObjectId 值,因为十六进制字符串值是词法的,就像 ObjectId 的内部排序一样。

集合中每个提供的 zone._id 值的 "last" 文档是哪些,按给定的原始文档 _id 值排序。