Значение $ $ $ lookup не отображается после $ group - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть 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")
}
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

}

1 Ответ

1 голос
/ 04 апреля 2020

вы можете выполнить проект как последний шаг после группировки, а $lookup также вы можете обрабатывать все это в группе, то, что вы включите в $group, будет доступно только вам в запросе, но позволяет скажем, вам нужно собрать power_usages_month документы, используемые каждым коммутатором в одном массиве в этом коммутаторе, но вам не нужна вся информация из этого power_usages_month, вам просто нужны current и time_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
}
...