2013-04-10 100 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