使用MongoDB投影数组

时间:2016-11-11 10:12:32

标签: mongodb mongodb-query aggregation-framework

我正在使用MongoDB的聚合管道,以我想要的形式获取我的文档。作为聚合的最后一步,我使用$project将文档放入最终形式。

但是我在投影和子文档数组时遇到了麻烦。这是我目前从aggrgation得到的:

{
  "_id": "581c8c3df1325f68ffd23386",
  "count": 14,
  "authors": [
    {
      "author": {
        "author": "57f246b9e01e6c6f08e1d99a",
        "post": "581c8c3df1325f68ffd23386"
      },
      "count": 13
    },
    {
      "author": {
        "author": "5824382511f16d0f3fd5aaf2",
        "post": "581c8c3df1325f68ffd23386"
      },
      "count": 1
    }
  ]
}

我想$project authors数组,以便返回:

{
  "_id": "581c8c3df1325f68ffd23386",
  "count": 14,
  "authors": [
    {
      "_id": "57f246b9e01e6c6f08e1d99a",
      "count": 13
    },
    {
      "_id": "5824382511f16d0f3fd5aaf2",
      "count": 1
    }
  ]
}

我将如何实现这一目标?

3 个答案:

答案 0 :(得分:7)

您可以在投射后将阵列展开并再次缠绕它。 像这样:

db.collectionName.aggregate([
{$unwind:'$authors'},
{$project:{_id:1,count:1,'author.id':'$authors.author.author','author.count':'$authors.count'}},
{$group:{_id:{_id:'$_id',count:'$count'},author:{$push:{id:'$author.id',count:'$author.count'}}}},
{$project:{_id:0,_id:'$_id._id',count:'$_id.count',author:1}}
])

上面的输出将是:

{ 
    "_id" : "581c8c3df1325f68ffd23386", 
    "author" : [
        {
            "id" : "57f246b9e01e6c6f08e1d99a", 
            "count" : 13.0
        }, 
        {
            "id" : "5824382511f16d0f3fd5aaf2", 
            "count" : 1.0
        }
    ], 
    "count" : 14.0
}

答案 1 :(得分:3)

我遇到了同样的问题,只是找到了一个简单优雅的解决方案,这一点在任何地方都没有提及,所以我想在这里分享一下:

您可以使用$ map迭代数组并投影每个作者。使用给定的结构,聚合应该看起来像这样

db.collectionName.aggregate([
  $project: {
    _id: 1,
    count:1,
    authors: {
      $map: {
        input: "$authors",
        as: "author",
        in: {
          id: "$$author.author.author",
          count: $$author.author.count
        }
      }
    } 
  }
])

希望这对正在寻找的人(例如我)有帮助:)

答案 2 :(得分:0)

问题:

"customFields" : [
    {
        "index" : "1",
        "value" : "true",
        "label" : "isOffline",
        "dataType" : "check_box",
        "placeholder" : "cf_isoffline",
        "valueFormatted" : "true"
    },

    {
        "index" : "2",
        "value" : "false",
        "label" : "tenure_extended",
        "dataType" : "check_box",
        "placeholder" : "cf_tenure_extended",
        "valueFormatted" : "false"
    }
],

答案:

db.subscription.aggregate([
  {$match:{"autoCollect" : false,"remainingBillingCycles" : -1,"customFields.value":"false", "customFields.label" : "isOffline"}},
  {$project: {first: { $arrayElemAt: [ "$customFields", 1 ] }}}
])