【问题标题】:mongodb aggregation framework - Fetch first document's field of the nested arraymongodb 聚合框架 - 获取嵌套数组的第一个文档的字段
【发布时间】:2013-04-11 15:32:23
【问题描述】:

考虑以下是我存储在集合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'}
                     ]
          }
}

现在使用 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);
};

【问题讨论】:

  • 你不会像这样使用 $slice (docs.mongodb.org/manual/reference/projection/slice) 运算符进行普通查询吗:db.col.find({_id: 'User1'}, {'likes.sublikes': {$slice: 1}})
  • 您引用的 Jira 中的未解决问题 (SERVER-4589) 是一个功能请求,因此 $at 运算符尚不存在。您可以在 Jira 中投票/观看该功能以跟踪进度。
  • 仅供参考,如果您希望它利用索引,您还应该在聚合管道的开头添加您的 $match。请参阅 MongoDB 文档中的 Optimizing Performance 详细信息。
  • @Stennie 你是绝对正确的。谢谢提醒...

标签: mongodb


【解决方案1】:

获得结果的最简单方法是使用普通的查找查询和$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 应该是性能最高的选项。

【讨论】:

    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多