Mongodb获得每个类别的计数

时间:2018-01-30 09:38:03

标签: mongodb nosql aggregation-framework lookup

我想了解每个类别的数量。我为此目的写了一个查询但这个查询返回了内容文档。我只想要返回每个类别内容和类别信息的计数。

分类收集:

{
    "_id" : ObjectId("5a6b98864f1408137f79e507"),
    "orderId" : 1,
    "parentId" : ObjectId("5a6b8fbd4f1408137f79e3b3"),
    "title_en" : "Foreign Movie",
    "contentTypes" : 1,
    "isEnabled" : true,
    "state" : 0,
    "expired" : Timestamp(1516998589, 1),
    "created" : Timestamp(1516998589, 2),
    "updated" : Timestamp(1516998589, 3)
},
{
    "_id" : ObjectId("5a6b98864f1408137f79e508"),
    "orderId" : 1,
    "parentId" : ObjectId("5a6b8fbd4f1408137f79e3b3"),
    "title_en" : "Foreign Series",
    "contentTypes" : 1,
    "isEnabled" : true,
    "state" : 0,
    "expired" : Timestamp(1516998589, 1),
    "created" : Timestamp(1516998589, 2),
    "updated" : Timestamp(1516998589, 3)
}

内容集合:

 {
    "_id" : ObjectId("5a6b8b734f1408137f79e2cc"),
    "categories" : [ 
        {
            "_id" : ObjectId("5a6b98864f1408137f79e507")
        }
    ],
    "status" : 0,
    "created" : Timestamp(1516997542, 4),
    "updated" : Timestamp(1516997542, 5)
}

汇总查询:

db.categories.aggregate([
{$match:{"parentId":{$ne : null}}},
  {$lookup:{from:"contents",localField:"_id",foreignField:"categories._id",as:"_content"}},

        { $group:
            {
                _id:"$_id",
                "data":{"$first":"$$ROOT"}   
            }
        }
    ,{$replaceRoot:{"newRoot":{"$mergeObjects":["$data"]}}},
])

上述查询的结果:

{
    "_id" : ObjectId("5a6b98864f1408137f79e507"),
    "orderId" : 1,
    "parentId" : ObjectId("5a6b8fbd4f1408137f79e3b3"),
    "title_en" : "Foreign Movie",
    "contentTypes" : 1,
    "isEnabled" : true,
    "state" : 0,
    "expired" : Timestamp(1516998589, 1),
    "created" : Timestamp(1516998589, 2),
    "updated" : Timestamp(1516998589, 3),
    "_content" : [ 
        {
        "_id" : ObjectId("5a6b8b734f1408137f79e2cc"),
        "categories" : [ 
            {
                "_id" : ObjectId("5a6b98864f1408137f79e507")
            }
        ],
        "status" : 0,
        "created" : Timestamp(1516997542, 4),
        "updated" : Timestamp(1516997542, 5)
    }
    ]
},
{
    "_id" : ObjectId("5a6b98864f1408137f79e508"),
    "orderId" : 1,
    "parentId" : ObjectId("5a6b8fbd4f1408137f79e3b3"),
    "title_en" : "Foreign Series",
    "contentTypes" : 1,
    "isEnabled" : true,
    "state" : 0,
    "expired" : Timestamp(1516998589, 1),
    "created" : Timestamp(1516998589, 2),
    "updated" : Timestamp(1516998589, 3),
    "_content" : [] /*array content is empty*/
}

当你展示它时,_content包含由contents返回的$lookup个文档,我没有这个结果,因为我只想要返回的类别信息与具有相同类别id的内容的数量如下查询:

目的结果:

{
    "_id" : ObjectId("5a6b98864f1408137f79e507"),
    "orderId" : 1,
    "parentId" : ObjectId("5a6b8fbd4f1408137f79e3b3"),
    "title_en" : "Foreign Movie",
    "contentTypes" : 1,
    "isEnabled" : true,
    "state" : 0,
    "expired" : Timestamp(1516998589, 1),
    "created" : Timestamp(1516998589, 2),
    "updated" : Timestamp(1516998589, 3),
    "contentCount":1,
    "_content" : [ 
        {
        "_id" : ObjectId("5a6b8b734f1408137f79e2cc")
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

您可以使用多个投影获得非常接近所请求结果的结果。使用“$ project”运算符,您可以随意移动大多数字段,但在这种情况下您需要多个阶段。

是的,您可以使用以下表达式获取您的contentCount:

contentCount: { $sum:{ $size: "$_content" } }

以下是我使用的完整查询:

db.categories.aggregate([
  {$match: {"parentId":{$ne : null}}},
  {$lookup:{from:"contents",localField:"_id",foreignField:"categories._id",as:"_content"}},
  { $group:
    {
      _id:"$_id",
      "data":{"$first":"$$ROOT"},
      contentCount: { $sum:{ $size: "$_content" } }
    }
  },
  {
     $project: {
       "orderId": "$data.orderId",
       "parentId": "$data.parentId",
       "title_en": "$data.title_en",
       "contentTypes": "$data.contentTypes",
       "isEnabled": "$data.isEnabled",
       "state": "$data.state",
       "expired": "$data.expired",
       "created": "$data.created",
       "updated": "$data.updated",
       "contentCount": "$contentCount",
       "_content": "$data._content"
     }
  },
  {
    $project: {
      "orderId": 1,
      "parentId": 1,
      "parentId": 1,
      "title_en": 1,
      "contentTypes": 1,
      "isEnabled": 1,
      "state": 1,
      "expired": 1,
      "created": 1,
      "updated": 1,
      "contentCount": 1,
      "_content._id" : 1
    }
  }
]).pretty()

这会在我的旧MongoDB 3.2中生成此结果,并提供您提供的数据:

{
        "_id" : ObjectId("5a6b98864f1408137f79e508"),
        "contentCount" : 0,
        "orderId" : 1,
        "parentId" : ObjectId("5a6b8fbd4f1408137f79e3b3"),
        "title_en" : "Foreign Series",
        "contentTypes" : 1,
        "isEnabled" : true,
        "state" : 0,
        "expired" : Timestamp(1516998589, 1),
        "created" : Timestamp(1516998589, 2),
        "updated" : Timestamp(1516998589, 3),
        "_content" : [ ]
}
{
        "_id" : ObjectId("5a6b98864f1408137f79e507"),
        "contentCount" : 1,
        "orderId" : 1,
        "parentId" : ObjectId("5a6b8fbd4f1408137f79e3b3"),
        "title_en" : "Foreign Movie",
        "contentTypes" : 1,
        "isEnabled" : true,
        "state" : 0,
        "expired" : Timestamp(1516998589, 1),
        "created" : Timestamp(1516998589, 2),
        "updated" : Timestamp(1516998589, 3),
        "_content" : [
                {
                        "_id" : ObjectId("5a6b8b734f1408137f79e2cc")
                }
        ]
}