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

mfr*_*het 2 mongodb mongodb-query aggregation-framework

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

我需要 :

  • 获取所有最后的条目
  • 关于一个领域
  • 喜欢:SELECT MAX(id),foreignKey FROM t_table GROUP BY foreignKey

我知道我们可以使用$ last和mongodb,但我根本不知道如何继续.

我试过了 :

db.collection.aggregate(
   [
     {
       $group:
         {
           _id: "$zone._id",
           lastRegistered: { $last: "$_id" }
         }
     }
   ]
)
Run Code Online (Sandbox Code Playgroud)

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

用例子编辑

根据这三个:

  { _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 
        },
Run Code Online (Sandbox Code Playgroud)

我需要得到 :

  { _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 
        },
Run Code Online (Sandbox Code Playgroud)

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

你懂我的意思吗 ?

Phi*_*ipp 5

$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",
         }
     }
   ]
)
Run Code Online (Sandbox Code Playgroud)


Bla*_*ven 5

您始终可以$$ROOT在分组边界上返回整个文档:

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

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

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

但是请注意,$group管道并不能保证保留文档顺序,因此,如果需要,您可以$sort再次:

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

在所有情况下,替代方法$$ROOT都是简单$last地为文档中您想要的每个字段明确声明。相比之下,$max运算符仅适用于指定的字段,因此,当您希望从分组边界中获取文档时,通常不需要这样做$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
    }
}
Run Code Online (Sandbox Code Playgroud)

更改后的输入是这样的:

{
    "_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
}
Run Code Online (Sandbox Code Playgroud)

ObjectId万一十六进制字符串值是词法的,就不要为正确的值而烦恼,就像ObjectId反正内部的。

zone._id集合中每个提供的值的“最后”文档是由_id给定的原始文档值排序的。