mongodb - 如何在分组时使用 $cond 检查同一数组中的空值进行聚合操作

标签 mongodb mongodb-query aggregation-framework

这是我的文档,

{
  "_id": "58aecaa3758fbff4176db088",
  "actualEndDate": "2017-02-27T00:00:00.000Z",
  "Details": [
    {         
      "projectId": "58a585f6758fbff4176dadb9",
    }
  ]
},
{
  "_id": "58aecac8758fbff4176db08b",
  "actualEndDate": "2017-03-12T00:00:00.000Z",
  "Details": [
    {         
      "projectId": "58a585f6758fbff4176dadb9",
    }
  ]
},
{
  "_id": "58aecac8758fbff4176db08c",
  "actualEndDate": null,
  "Details": [
    {         
      "projectId": "58a585f6758fbff4176dadb9",
    }
  ]
}

我需要对这些进行分组,在我的查询中,我需要找到“actualEndDate”的 $max,只有当所有“actualEndDate”字段都不为空时才有条件。

我试过这样的,

{ 
    $group: 
           {
              _id: '$Details.projectId',
              actualEndDate: 
                   { 
                     $cond: { 
                             if: { $ne: [ $actualEndDate, null] }, 
                             then: $actualEndDate, else: null
                            }
                   }
            }
}

这样我就可以得到像这样的预期结果

{
   "projectId": "58a585f6758fbff4176dadb9",
   "actualEndDate": null,
}

如果示例不包含 { "_id": "58aecac8758fbff4176db08c"} 记录,那么我希望结果具有 actualEndDate 作为其他两个文档的最大值

{
   "projectId": "58a585f6758fbff4176dadb9",
   "actualEndDate": "2017-03-12T00:00:00.000Z",
}

感谢任何帮助。

最佳答案

您可以 $sort您的 actualDate 字段,$unwind你的 Details 数组然后 $group 只取 $first date 将确保这是最近的日期:

db.data.aggregate([{
    $sort: {
        "actualEndDate": -1
    }
}, {
    $unwind: "$Details"
}, {
    $group: {
        _id: "$Details.projectId",
        actualEndDate: {
            $first: "$actualEndDate"
        }
    }
}]);

如果指定的 projectId 的至少一个日期为 null,如果您想返回一个 null date,则以下操作将完成这项工作:

db.data.aggregate([{
    $sort: {
        "actualEndDate": -1
    }
}, {
    $unwind: "$Details"
}, {
    $group: {
        _id: "$Details.projectId",
        dates: {
            $push: "$actualEndDate"
        }
    }
}, {
    $project: {
        projectId: "$_id",
        actualEndDate: {
            $cond: {
                if: {
                    $setIsSubset: [
                        [null], "$dates"
                    ]
                },
                then: null,
                else: { $arrayElemAt: ["$dates", 0] }
            }
        }
    }
}]);

思路是$push将所有日期放入一个新数组中,并进行投影以在数组中发现 null 时返回 null,否则返回数组的第一个元素(值在第一阶段)

关于mongodb - 如何在分组时使用 $cond 检查同一数组中的空值进行聚合操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43361587/

相关文章:

javascript - Node : how to know if a value is in a collection of a MongoDB database?

node.js - 如何使用 Mongoose 检查是否存在现有的 MongoDB 连接?

java - Mongodb java驱动程序查询转换

mongodb - 如何在 MongoDB 中执行基于值的 Order By?

javascript - Mongoose - 使用 post 方法创建一个新的空集合

node.js - Mongoose中如何查询基于父模型的子模型限制结果

Mongodb:在两个字段的数组上创建索引

MongoDB,即使查询字段形成分区,也会减慢查询速度吗?

javascript - 如何使用另一个集合中的字段值更新 Mongodb 集合中的文档

mongodb - 在mongodb聚合管道中将毫秒转换为日期以进行分组?