2015-08-21 74 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'或任何其他分組累加器。因此使整個陳述無效。甚至在幾次修改之後。 –