繁体   English   中英

MongoDB 文档的总返回计数或 0

[英]MongoDB aggregate return count of documents or 0

我有以下聚合查询:

db.user.aggregate()
    .match({"business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf")})
    .lookup({
        'localField': 'profile_id',
        'from': 'profile',
        'foreignField' : '_id',
        'as': 'profile'
    })
    .unwind("$profile")
    .match({"profile.type" : "consultant"})
    .group({_id:"$business_account_id", count:{$sum:1}})

我的目标是计算有多少顾问用户属于给定的公司。

使用上面的查询,如果至少有一个用户属于提供的 business_account_id,我会得到一个正确的计数值。

但如果没有用户, .match({"business_account_id": ObjectId("5e3377bcb1dbae5124e4b6bf")})将返回空(0 个文档)结果。

如果没有分配给公司的用户,我如何获得count: 0

我尝试了许多基于其他线程的方法,但我无法count: 0

更新 1

我的问题的一个简单版本:

用户集合

{
    "_id" : ObjectId("5e36beb7b1dbae5124e4b6dc"),
    "business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf"),
},
{
    "_id" : ObjectId("5e36d83db1dbae5124e4b732"),
    "business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf"),
}

使用以下聚合查询:

db.getCollection("user").aggregate([
        { "$match" : { 
                "business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf")
            }
        }, 
        { "$group" : { 
                "_id" : "$business_account_id", 
                "count" : { "$sum" : 1 }
            }
        }
]);

我得到:

{ 
    "_id" : ObjectId("5e3377bcb1dbae5124e4b6bf"), 
    "count" : 2
}

但是,如果我查询一个不存在的 ObjectId,例如:

db.getCollection("user").aggregate([
        { "$match" : { 
                "business_account_id" : ObjectId("5e335c873e8d40676928656d")
            }
        }, 
        { "$group" : { 
                "_id" : "$business_account_id", 
                "count" : { "$sum" : 1 }
            }
        }
]);

我得到一个完全空的结果。 我希望得到:

{ 
    "_id" : ObjectId("5e335c873e8d40676928656d"), 
    "count" : 0
}

由于您匹配不存在的business_account_id值,聚合过程将停止。

解决方法:如果匹配没有结果,我们使用$facet运算符并行执行 2 次聚合以获取default值。

注意:确保user集合至少有 1 条记录,否则这将不起作用

db.user.aggregate([
  {
    $facet: {
      not_found: [
        {
          $project: {
            "_id": ObjectId("5e3377bcb1dbae5124e4b6bf"),
            "count": { $const: 0 }
          }
        },
        {
          $limit: 1
        }
      ],
      found: [
        {
          "$match": {
            "business_account_id": ObjectId("5e3377bcb1dbae5124e4b6bf")
          }
        },
        {
          "$group": {
            "_id": "$business_account_id",
            "count": { "$sum": 1 }
          }
        }
      ]
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          {
            $arrayElemAt: ["$not_found", 0]
          },
          {
            $arrayElemAt: ["$found", 0]
          }
        ]
      }
    }
  }
])

Mongo游乐场

问题的根源在于,如果user集合中没有满足初始$match的文档,则没有任何内容可以传递到管道的下一阶段。 如果business_account_id确实存在于某处(可能是另一个集合?),则针对该集合运行聚合,以便初始匹配找到至少一个文档。 然后使用 $lookup 查找用户。 如果您使用的是 MongoDB 3.6+,您可以结合用户和配置文件查找。 最后,使用$size计算 users 数组中的元素。

(您可能需要调整集合和字段名称)

db.businesses.aggregate([
    {$match:{_id : ObjectId("5e3377bcb1dbae5124e4b6bf")}},
    {$project: { _id:1 }},
    {$lookup:{
          from: "users",
          let: {"busId":"$_id"},
          as: "users",
          pipeline: [
               {$match: {$expr:{$eq:[
                                "$$busId",
                                "$business_account_id"
               ]}}},
               {$lookup:{
                    localField: "profile_id",
                    from: "profile",
                    foreignField : "_id",
                    as: "profile"
               }},
               {$match: { "profile.type" : "consultant"}}
          ]
     }},
     {$project: {
           _id: 0,
           business_account_id: "$_id",
           count:{$size:"$users"} 
     }}
])

操场

暂无
暂无

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

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