2013-04-10 142 views
7

考慮下面的第一個文件的領域是存儲在收集我的文檔UsersMongoDB的聚合框架 - 獲取嵌套數組

{ 
    _id : "User1", 
    joined : ISODate("2011-03-02"), 
    likes : { 
      sublikes: [ 
         {WebsiteID:'001': WebsiteName: 'ABCD'}, 
         {WebsiteID:'002': WebsiteName: '2BC2'}, 
         {WebsiteID:'003': WebsiteName: '3BC3'}, 
         //........... 
         //........... 
         {WebsiteID:'999999': WebsiteName: 'SOME_NAME'} 
        ] 
      } 
} 

現在使用MongoDB的聚合框架,我需要獲取該

collection.aggregate([ 
         { $project: { 
          _id: 1, 
          "UserID": "$_id", 
          "WebsiteName": "$likes.sublikes[0]['WebsiteName']" 
         } 
         }, 
         { $match: { _id: 'User1'} } 
         ], function (err, doc) { 
///Not able to get the WebsiteName: 'ABCD' 
}); 

如果我用$unwind文檔變得散裝(特別是在上述情況下),所以我不想放鬆它得到一個數組只有第一項(不考慮別人的)

任何人都可以給我提示如何訪問是和重命名該字段?


更新 1:即使我試圖與 "WebsiteName": "$likes.sublikes.0.WebsiteName"項目。沒:-(

更新工作 2:開放式問題 - https://jira.mongodb.org/browse/SERVER-4589

截至目前$at不起作用拋出一個錯誤:

{ [MongoError: exception: invalid operator '$at'] 
    name: 'MongoError', 
    errmsg: 'exception: invalid operator \'$at\'', 
    code: 15999, 
    ok: 0 } 

至此使用 $unwind

// Array Remove - By John Resig (MIT Licensed) 
Array.prototype.remove = function(from, to) { 
    var rest = this.slice((to || from) + 1 || this.length); 
    this.length = from < 0 ? this.length + from : from; 
    return this.push.apply(this, rest); 
}; 
+0

你會不會轉而使用與$切片(http://docs.mongodb.org/manual/reference/projection/slice/)運算符,像這樣普通的查詢:'db.col.find({_ ID:' User1'},{'likes.sublikes':{$ slice:1}})'? – Sammaye 2013-04-10 13:14:46

+1

開放問題吉拉,你已經引用(SERVER-4589)是一款功能要求,因此'$ at'運營商還不存在。您可以投票/觀看Jira中的功能以跟蹤進度。 – Stennie 2013-04-11 06:54:39

+1

僅供參考,你也應該,如果你希望它採取指數的優勢有在匯聚管道的開始你的'$ match'。請參閱MongoDB文檔中的[優化性能](http://docs.mongodb.org/manual/core/aggregation/#optimizing-performance)詳細信息。 – Stennie 2013-04-11 07:11:23

回答

10

實現你的結果的最簡單方法使用常規的查找查詢和$slice操作:

db.collection.find({_id: "User1"}, {"likes.sublikes": {$slice: 1}}) 

聚集框架(如MongoDB的2.4.1)不支持$slice或數組索引(投票/手錶功能要求:SERVER-6074SERVER-4589)。

你可以使用$unwind$group聚合框架和$first運營商,如做到這一點:

db.collection.aggregate([ 
    { $match: { 
     _id : "User1" 
    }}, 
    { $unwind: "$likes.sublikes" }, 
    { $group: { 
     _id: "$_id", 
     like: { $first: "$likes.sublikes" } 
    }}, 
    { $project: { 
     _id: 0, 
     "UserID": "$_id", 
     "WebsiteName": "$like.WebsiteName" 
    }} 
]) 

正常$slice應該是最高效的選擇。

+1

非常好..它的工作原理... – 2013-04-12 07:24:47