【问题标题】:Check if subdocument in range complies with a condition检查范围内的子文档是否符合条件
【发布时间】:2018-06-20 15:23:55
【问题描述】:

我正在处理一个 mongoDB 查询。

我有几个文档,我查询了以下结果:

{
    "_id" : 1000.0,
    "date" : ISODate("2018-05-25T00:20:00.000Z"),
    "value" : true
}

{
    "_id" : 1000.0,
    "date" : ISODate("2018-05-25T00:26:00.000Z"),
    "value" : false
}

{
    "_id" : 1000.0,
    "date" : ISODate("2018-05-25T00:30:00.000Z"),
    "value" : false
}

过滤了原始文档,因此我只能获得现在之前最后 15 分钟内的文档,并且无法知道该时间范围内有多少条目。

我需要扩展我现有的查询,以便它返回基于“值”的状态。如果有 no true 我需要一个状态 0,如果有 至少 1 但不仅是 true 我需要一个状态 1 ,如果只有 true 我需要状态 2。

例如:

{
    "_id" : 1000,
    "status" : 1
},
{
    "_id" : 1001,
    "status" : 2
}

有没有办法使用 mongoDB 来完成这个任务?或者在java端做它会更好/更容易吗?注意数据库中有几个_id。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您可以将每个组中的所有值收集到一个数组中(使用$group$push),然后使用$switch 应用您的逻辑。要确定数组是否包含任何true 值或所有值都是true,您可以使用$anyElementTrue$allElementsTrue

    db.col.aggregate([
        {
            $group: {
                _id: "$_id",
                values: { $push: "$value" }
            }
        },
        {$unwind:"$values"},
        {
            $project: {
                _id: 1,
                status: {
                    $switch: {
                        branches: [
                            { case: { $allElementsTrue: "$values" }, then: 2 },
                            { case: { $anyElementTrue: "$values" }, then: 1 },
                        ],
                        default: 0
                    }
                }
            }
        }
    ])
    

    【讨论】:

    • 这种方法似乎是最直接的一种。但是,无论值数组的内容如何,​​我都会得到一个 2 (allElementsTrue) 值。知道为什么会这样吗?
    • 我想我明白了为什么总是得到一个 allElementsTrue = true 的原因。当运行上面的查询时,我得到的结果为` { "_id" : 1498.0, "values" : [ [ false, true ] ] } ` 并且根据docs, allElemetsTrue 不会下降到嵌套数组中但在顶层评估数组。如何使“值”成为顶级数组?
    • @SebastianR 我认为您的三个示例文档总是将value 作为简单的布尔值。由于它们具有相同的 _id,我猜这些文档是一些未知的先前聚合的结果(因为在 Mongo 中不能有重复的 _id)。在这种情况下,您不需要$unwind。我理解正确吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 2023-04-03
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    相关资源
    最近更新 更多