2015-08-21 41 views
1

我实际上在处理MongoDb时遇到麻烦。MongoDb,查询最后一个,并由

我需要:

  • 得到有关现场
  • 像所有的最后条目
  • 的:SELECT MAX(ID),外键FROM t_table GROUP BY FOREIGNKEY

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

我想:

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线等等..))

你知道我是什么意思?

+0

代码示例似乎与文档示例不匹配。您指的是您的文档中不存在的字段'$ foreignField'。另外,你正在用'_id'进行分组,因为'_id'总是唯一的(除非你之前做了一个'$ unwind'聚合步骤)。也许你的意思是按'zone._id'分组? – Philipp

+0

这是一个例子。即时将要修改它以配合真实的背景 – mfrachet

回答

3

您可以随时使用$$ROOT返回分组边界上的整个文件:

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 } } 
]) 

在所有情况下,alterate到$$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 
    } 
} 

改变的输入是这样的:

{ 
    "_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值来自集合,按原始文件_id给出的值排列。

+0

我试过这个,但结果集只有一行,而不是两个在我的情况下 – mfrachet

+0

@Skahrz对您发布的数据不可能。你有两个不同的'zone._id'值,因此你得到两个结果。这就是'$ group'所做的。我真的需要在发布的三个项目中发布“我的”结果吗?或者你可以自己做这个吗?我怀疑你正在抽象你的“真实”的代码和数据,并在你的“真实”代码中错误地应用我在这里找到的东西。 –

+0

@Skahrz因此,我已经提供了来自聚合管道的输出,正如所使用的那样,以及输入文档(从您自己的示例中镜像)用作生成结果的源,我认为这不仅仅是答案“解释性”和工作示例,这也认为只有一个其他尝试在答案(奇怪地upvoted,虽然完全语法不正确,我不是说只是输入错误),不能解决问题。正如我所展示的结果,显然有。我希望那不是你的喜欢。 –

3

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

尝试的$小组赛阶段前增加了$排序阶段获得升序日期顺序整理资料:

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

我试过这一个,但结果集只有一行,而不是两个在我的情况下 – mfrachet

+0

@Skahrz请仔细检查文档的'zone._id'值确实是不同的。 – Philipp

+1

我认为这里的主要问题是其他字段,如“control_id”,“actif”缺少'$ last'或任何其他分组累加器。因此使整个陈述无效。甚至在几次修改之后。 –