【问题标题】:$project $lookup value not shown after $group$group 之后未显示 $project $lookup 值
【发布时间】:2020-04-04 13:21:52
【问题描述】:

我有 2 个相关的收藏,我想做一个 $lookup

  1. 开关
{ 
    "_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "relay" : NumberInt(1), 
    "name" : "Lampu Tengah", 
    "voltage" : 80.0, 
    "duration" : null, 
    "status" : true, 
    "triggered_by" : ObjectId("5e5fd642fce106005319e884"), 
    "created_at" : ISODate("2020-04-01T15:41:36.588+0000"), 
    "updated_at" : ISODate("2020-04-01T22:59:39.261+0000")
}
{ 
    "_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "relay" : NumberInt(2), 
    "name" : "Kipas Angin", 
    "voltage" : 100.0, 
    "duration" : null, 
    "status" : true, 
    "triggered_by" : ObjectId("5e5fd642fce106005319e884"), 
    "created_at" : ISODate("2020-04-01T15:45:48.099+0000"), 
    "updated_at" : ISODate("2020-04-01T15:45:48.099+0000")
}
  1. power_usage_month
{ 
    "_id" : ObjectId("5e87edffffba850e8d72ce27"), 
    "switch_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 19.345, 
    "time_minutes" : NumberInt(123), 
    "created_at" : ISODate("2020-04-02T15:01:37.521+0000"), 
    "updated_at" : ISODate("2020-04-02T15:01:37.521+0000")
}
{ 
    "_id" : ObjectId("5e87ee06ffba850e8d72ce28"), 
    "switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 17.5, 
    "time_minutes" : NumberInt(123), 
    "created_at" : ISODate("2020-04-03T20:35:09.870+0000"), 
    "updated_at" : ISODate("2020-04-03T20:35:09.871+0000")
}
{ 
    "_id" : ObjectId("5e87ee0cffba850e8d72ce29"), 
    "switch_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 19.345, 
    "time_minutes" : NumberInt(124), 
    "created_at" : ISODate("2020-04-04T01:45:00.000+0000"), 
    "updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{ 
    "_id" : ObjectId("5e87ee13ffba850e8d72ce2a"), 
    "switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 17.5, 
    "time_minutes" : NumberInt(124), 
    "created_at" : ISODate("2020-04-04T01:45:00.000+0000"), 
    "updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{ 
    "_id" : ObjectId("5e87ee18ffba850e8d72ce2b"), 
    "switch_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 19.345, 
    "time_minutes" : NumberInt(125), 
    "created_at" : ISODate("2020-04-04T01:45:00.000+0000"), 
    "updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{ 
    "_id" : ObjectId("5e87ee20ffba850e8d72ce2c"), 
    "switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 17.5, 
    "time_minutes" : NumberInt(125), 
    "created_at" : ISODate("2020-04-04T01:45:00.000+0000"), 
    "updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{ 
    "_id" : ObjectId("5e87ee26ffba850e8d72ce2d"), 
    "switch_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 19.345, 
    "time_minutes" : NumberInt(126), 
    "created_at" : ISODate("2020-04-04T01:45:00.000+0000"), 
    "updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{ 
    "_id" : ObjectId("5e87ee2dffba850e8d72ce2e"), 
    "switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "current" : 17.5, 
    "time_minutes" : NumberInt(126), 
    "created_at" : ISODate("2020-04-04T01:45:00.000+0000"), 
    "updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}

现在我想使用 $lookup 和 $project 我要显示的字段“加入”这些集合,但显然 $project 值在我执行 $group 后不会显示。这是我的查询

db.getCollection("power_usages_month").aggregate(
    [
        { 
            "$project" : { 
                "_id" : NumberInt(0), 
                "power_usages_month" : "$$ROOT"
            }
        }, 
        { 
            "$lookup" : { 
                "localField" : "power_usages_month.switch_id", 
                "from" : "switches", 
                "foreignField" : "_id", 
                "as" : "switches"
            }
        }, 
        { 
            "$unwind" : { 
                "path" : "$switches", 
                "preserveNullAndEmptyArrays" : false
            }
        }, 
        { 
            "$group" : { 
                "_id" : "$power_usages_month.switch_id",
                "sum_current" : { 
                    "$sum" : "$power_usages_month.current"
                }
            }
        }, 
        { 
            "$project" : { 
                "switch_id" : "$_id", 
                "device_id" : "$switches.device_id",
                "sum_current" : "$sum_current", 
                "voltage" : "$switches.voltage",
            }
        }
    ], 
    { 
        "allowDiskUse" : true
    }
);

根据结果,"device_id" : "$switches.device_id","voltage" : "$switches.voltage" 无法按预期出现:

{ 
    "_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "sum_current" : 70.0
}
{ 
    "_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "switch_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "sum_current" : 77.38
}

怎么可能?请告诉我查询的错误..

编辑:这是我想要的结果

{ 
    "_id" : ObjectId("5e8454bc95c85ca0c33a9463"), 
    "switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
    "sum_current" : 70.0,
    "voltage" : 80.0

}
{ 
    "_id" : ObjectId("5e8453c095c85ca0c33a9461"), 
    "switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
    "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"), 
    "sum_current" : 77.38,
    "voltage" : 100.0

}

【问题讨论】:

    标签: mongodb nosql bson nosql-aggregation


    【解决方案1】:

    您可以在分组和$lookup 之后将项目作为最后一步 你也可以在小组中处理所有这些, 您将在$group 中包含的内容将仅在您的查询中可用, 但是假设您需要在该交换机的一个数组中收集每个交换机使用的power_usages_month 文档, 但是您不需要来自 power_usages_month 的所有信息,例如您只需要 currenttime_minutes

    你可以这样做

    db.powerUsageMonth.aggregate(
        [
            {
                $match: {}
            },
            {
                $lookup: {
                    from: 'switches',
                    localField: 'switch_id',
                    foreignField: '_id',
                    as: 'switch'
                }
            },
            {
                $unwind: '$switch'
            },
            {
                $group: {
                    _id: '$switch._id',
                    sum_current: {
                        $sum: '$current'
                    },
                    switchInfo: {
                        $first: '$switch'
                    },
                    powerUsageDocs: {
                        $addToSet: '$$ROOT'
                    }
                }
            },
            {
                $project: {
                    _id: 1,
                    sum_current: 1,
                    switchInfo: 1,
                    'powerUsageDocs.current': 1,
                    'powerUsageDocs.time_minutes': 1,
                }
            }
        ]
    )
    

    这将返回一组开关及其总电流和开关信息(如果您不需要所有开关信息,您也可以在此处进行一些投影),以及与此开关相关的电源使用文档(投影后)

    结果会是这样的

    {
        "_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
        "sum_current" : 70,
        "switchInfo" : {
            "_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
            "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
            "relay" : 2,
            "name" : "Kipas Angin",
            "voltage" : 100,
            "duration" : null,
            "status" : true,
            "triggered_by" : ObjectId("5e5fd642fce106005319e884"),
            "created_at" : ISODate("2020-04-01T15:45:48.099Z"),
            "updated_at" : ISODate("2020-04-01T15:45:48.099Z")
        },
        "powerUsageDocs" : [
            {
                "current" : 17.5,
                "time_minutes" : 125
            },
            {
                "current" : 17.5,
                "time_minutes" : 123
            },
            {
                "current" : 17.5,
                "time_minutes" : 126
            },
            {
                "current" : 17.5,
                "time_minutes" : 124
            }
        ]
    }
    {
        "_id" : ObjectId("5e8453c095c85ca0c33a9461"),
        "sum_current" : 77.38,
        "switchInfo" : {
            "_id" : ObjectId("5e8453c095c85ca0c33a9461"),
            "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
            "relay" : 1,
            "name" : "Lampu Tengah",
            "voltage" : 80,
            "duration" : null,
            "status" : true,
            "triggered_by" : ObjectId("5e5fd642fce106005319e884"),
            "created_at" : ISODate("2020-04-01T15:41:36.588Z"),
            "updated_at" : ISODate("2020-04-01T22:59:39.261Z")
        },
        "powerUsageDocs" : [
            {
                "current" : 19.345,
                "time_minutes" : 124
            },
            {
                "current" : 19.345,
                "time_minutes" : 126
            },
            {
                "current" : 19.345,
                "time_minutes" : 123
            },
            {
                "current" : 19.345,
                "time_minutes" : 125
            }
        ]
    }
    

    更新

    如果您只需要有关交换机的信息, 您还需要获得瓦特,即 = 总电流 * 每个开关的电压, 我们可以在$project 中做到这一点,我们可以将$multiply 运算符添加到$project 管道中,它将开关的电压乘以我们刚刚在$group 管道中计算的总电流

    db.powerUsageMonth.aggregate(
        [
            {
                $match: {}
            },
            {
                $lookup: {
                    from: 'switches',
                    localField: 'switch_id',
                    foreignField: '_id',
                    as: 'switch'
                }
            },
            {
                $unwind: '$switch'
            },
            {
                $group: {
                    _id: '$switch._id',
                    switch_id: { $first: '$switch._id' },
                    device_id: { $first: '$switch.device_id' },
                    voltage: { $first: '$switch.voltage' },
                    sum_current: {
                        $sum: '$current'
                    }
                }
            },
            {
                $project: {
                    _id: 1,
                    switch_id: 1,
                    device_id: 1,
                    voltage: 1,
                    sum_current: 1,
                    watt: { $multiply: [ "$voltage", "$sum_current" ] }
                }
            }
        ]
    )
    

    这将产生一个形式为

    的数组
    {
        "_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
        "switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
        "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
        "voltage" : 100,
        "sum_current" : 70,
        "watt" : 7000
    }
    {
        "_id" : ObjectId("5e8453c095c85ca0c33a9461"),
        "switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
        "device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
        "voltage" : 80,
        "sum_current" : 77.38,
        "watt" : 6190.4
    }
    

    【讨论】:

    • 感谢您的回答,但这似乎不是我想要的结果格式。我编辑了所需的结果格式,请看一下:)
    • 我已经更新了我的答案,你现在可以检查一下吗?另外,不要忘记将 collectionName 'powerUsageMonth' 替换为您自己的
    • 太棒了!谢谢你解决我的问题:D
    • 嗯,再回答一个先生,我想在voltage字段之后添加乘法值,我的查询是watt: {$first: {$multiply: ["$sum_current", '$switch.voltage']}}但它不能调用sum_current组,如何实现?
    • 好的,我刚刚再次更新了我的答案以添加每个开关的瓦特
    猜你喜欢
    • 2019-05-07
    • 1970-01-01
    • 2018-08-19
    • 2019-09-03
    • 2019-05-11
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多