简体   繁体   English

mongodb聚合框架 - 获取嵌套数组的第一个文档的字段

[英]mongodb aggregation framework - Fetch first document's field of the nested array

Consider the following is my document stored in collection Users 考虑以下是我的文档存储在集合Users

{
  _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'}
                     ]
          }
}

Now using mongodb aggregation framework I need to fetch that 现在使用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'
});

If I use $unwind the document becomes bulk (specifically in the above case), So I don't want to unwind it for getting only first item in an array (irrespective of others) 如果我使用$unwind ,文档将变为批量(特别是在上面的情况下),所以我不想放松它只获取数组中的第一项(不管其他人)

Can anyone give me hints on how to access is and rename that field? 任何人都可以给我提示如何访问并重命名该字段?


Update 1: Even I tried to project with "WebsiteName": "$likes.sublikes.0.WebsiteName" . 更新 1:即使我尝试使用"WebsiteName": "$likes.sublikes.0.WebsiteName" Didn't work :-( 没工作:-(

Update 2: Open issue - https://jira.mongodb.org/browse/SERVER-4589 更新 2:未解决的问题 - https://jira.mongodb.org/browse/SERVER-4589

As of now $at does not work. 截至目前, $at不起作用。 Throws an error: 抛出错误:

// 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);
};

Till then using $unwind 然后使用$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); }; 

The easiest way to achieve your result is using a normal find query and the $slice operator: 实现结果的最简单方法是使用常规查找查询和$slice运算符:

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

The aggregation framework (as at MongoDB 2.4.1) does not support $slice or array indexes (vote/watch feature requests: SERVER-6074 and SERVER-4589 ). 聚合框架(如MongoDB 2.4.1)不支持$slice或数组索引(投票/监视功能请求: SERVER-6074SERVER-4589 )。

You could do this in aggregation framework using $unwind , $group and the $first operator, eg: 您可以使用$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"
    }}
])

The normal $slice should be the most performant option. 正常的$slice应该是性能最高的选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM