在mongodb中使用单个查询进行多个计数

时间:2018-08-30 03:03:02

标签: mongodb mongodb-query aggregation-framework

我是Mongo Db的新手,希望在此查询方面有所帮助。在过去的几天里,我一直在梳理这里的头发,以查看是否可以找到与查询有关的任何内容,但是没有运气。

我有一个集合,其文档结构与以下类似:

_id: xyz
Movieid: 123
MovieName: Titanic
ReleaseDate: 2000-01-01

_id: uvw
Movieid: 456
MovieName: Titanic II
ReleaseDate: 2018-01-01

_id: pqr
Movieid: 789
MovieName: Titanic III
ReleaseDate: 

我希望在以下3个单独的列中以总电影,有发行日期的电影和无发行日期的电影的计数形式输出:

Total   |   Released  |     UnReleased
 3      |       2     |          1

我能够编写单个查询来执行计数,但是我无法将所有内容成功整合到一个查询中。最终目标是创建一个视图,将这些计数作为输出。我尝试使用$ and这样的运算符,但似乎无法使查询按预期工作。...据我所知:

db.getCollection("Movies").aggregate(
    $and: [
{ 
            "$match" : 
                {"ReleaseDate":{$exists:true}}
            }
        , 
        { 
            $count:"Total"
        },
        { 
            "$match" : 
                {"ReleaseDate":{$exists:true,$nin:[""]}}
            }
        , 
        { 
            $count:"Released"
        },

        { 
            "$match" : 
                {"ReleaseDate":{$exists:true,$in:[""]}}
            }
        , 
        { 
            $count:"Unreleased"
        }


    ]
);

3 个答案:

答案 0 :(得分:10)

您可以尝试以下$facet聚合

$count聚合将始终只为单个匹配($match)条件提供计数。因此,您需要将每个计数进一步分为多个部分,这就是$facet通过在同一阶段的同一组输入文档上处理多个聚合管道来提供的功能。

db.collection.aggregate([
  { "$facet": {
    "Total": [
      { "$match" : { "ReleaseDate": { "$exists": true }}},
      { "$count": "Total" },
    ],
    "Released": [
      { "$match" : {"ReleaseDate": { "$exists": true, "$nin": [""] }}},
      { "$count": "Released" }
    ],
    "Unreleased": [
      { "$match" : {"ReleaseDate": { "$exists": true, "$in": [""] }}},
      { "$count": "Unreleased" }
    ]
  }},
  { "$project": {
    "Total": { "$arrayElemAt": ["$Total.Total", 0] },
    "Released": { "$arrayElemAt": ["$Released.Released", 0] },
    "Unreleased": { "$arrayElemAt": ["$Unreleased.Unreleased", 0] }
  }}
])

Output

[{
    "Total": 3,
    "Released": 2,
    "Unreleased": 1
}]

答案 1 :(得分:1)

您可以使用以下汇总。

$gt > null-检查聚合表达式中是否存在字段。

$cond$sum根据发布日期过滤器输出0和1。

$add将已发布和未发布的计数都添加到输出总计中。

db.Movies.aggregate([
 {"$group":{
   "_id":null,
   "Unreleased":{"$sum":{"$cond":[{"$and":[{"$gt":["$ReleaseDate",null]},{"$ne":["$ReleaseDate",""]}]},0,1]}},
   "Released":{"$sum":{"$cond":[{"$and":[{"$gt":["$ReleaseDate",null]},{"$ne":["$ReleaseDate",""]}]},1,0]}}
 }},
 {"$addFields":{"Total":{"$add":["$Unreleased","$Released"]}}}
])

答案 2 :(得分:0)

db.Movies.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $group: {
                _id: null,
                Total: {
                    $sum: 1
                },
                docs: {
                    $push: '$$ROOT'
                }
            }
        },

        // Stage 2
        {
            $project: {
                _id: 0,
                Total: 1,
                Released: {
                    $filter: {
                        input: "$docs",
                        as: "doc",
                        cond: {
                            $ne: ["$$doc.ReleaseDate", ""]
                        }
                    }
                },
                Unreleased: {
                    $filter: {
                        input: "$docs",
                        as: "doc",
                        cond: {
                            $eq: ["$$doc.ReleaseDate", ""]
                        }
                    }
                },
            }
        },

        // Stage 3
        {
            $project: {
                Total: 1,
                Released: {
                    $size: '$Released'
                },
                UnReleased: {
                    $size: '$Unreleased'
                }
            }
        },

    ]



);