mongodb中的条件分组依据

时间:2018-12-03 08:45:21

标签: mongodb mongodb-query aggregation-framework

我有一个包含如下数据的集合:

{
    "_id" : "cae86e275c2364550ad508f4379de992",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-29",
    "data1" : "Tablet",
    "var2" : 8,
    "month" : "2018-11",
    "timestamp" : 1543492800,
    "week" : "2018-48",
    "year" : "2018"
},
{
    "_id" : "f01c732da18e3a9cf7b6b4cb9a308b61",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-29",
    "data1" : "Mobile Phone",
    "var2" : 125,
    "month" : "2018-11",
    "timestamp" : 1543492800,
    "week" : "2018-48",
    "year" : "2018"
},
{
    "_id" : "c6412346efb2f784aadfbb6a1b44b11b",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-28",
    "data1" : "Tablet",
    "var2" : 3,
    "month" : "2018-11",
    "timestamp" : 1543406400,
    "week" : "2018-48",
    "year" : "2018"
},
{
    "_id" : "e8ebc0b11d9d28956daf58dec40832bf",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-22",
    "data1" : "Mobile Phone",
    "var2" : 20,
    "month" : "2018-11",
    "timestamp" : 1542888000,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "7de4fcd246e16b21aabd025c7379e6cc",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-22",
    "data1" : "Tablet",
    "var2" : 1,
    "month" : "2018-11",
    "timestamp" : 1542888000,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "48e2a67de454f26b939e5ec063060c49",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 1,
    "cost" : 0,
    "day" : "2018-11-28",
    "data1" : "Desktop",
    "var2" : 110,
    "month" : "2018-11",
    "timestamp" : 1543406400,
    "week" : "2018-48",
    "year" : "2018"
},
{
    "_id" : "d2a2cc40632abc4e82c546d36937a9bd",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-29",
    "data1" : "Desktop",
    "var2" : 123,
    "month" : "2018-11",
    "timestamp" : 1543492800,
    "week" : "2018-48",
    "year" : "2018"
},
{
    "_id" : "44dd41225a07e2a55c0da832d6ba6e7e",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 1,
    "cost" : 0,
    "day" : "2018-11-21",
    "data1" : "Desktop",
    "var2" : 27,
    "month" : "2018-11",
    "timestamp" : 1542801600,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "6ec03cedcf3b93f4a21d000112bf62b1",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-28",
    "data1" : "Mobile Phone",
    "var2" : 121,
    "month" : "2018-11",
    "timestamp" : 1543406400,
    "week" : "2018-48",
    "year" : "2018"
},
{
    "_id" : "1f26b3bc8c56eb310f217e0ceac2696a",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-21",
    "data1" : "Tablet",
    "var2" : 3,
    "month" : "2018-11",
    "timestamp" : 1542801600,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "9c9c5b592e22c6588e02dbb5a5deb4c0",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-21",
    "data1" : "Mobile Phone",
    "var2" : 34,
    "month" : "2018-11",
    "timestamp" : 1542801600,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "0def2966dfd3034c112ab881fb42199b",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-22",
    "data1" : "Desktop",
    "var2" : 36,
    "month" : "2018-11",
    "timestamp" : 1542888000,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "2e26d5c99c75332908464812e5221aa2",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-23",
    "data1" : "Mobile Phone",
    "var2" : 27,
    "month" : "2018-11",
    "timestamp" : 1542974400,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "e6569c691671ee22805f555a0c13ee14",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : null,
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : "2018-11-23",
    "data1" : "Desktop",
    "var2" : 28,
    "month" : "2018-11",
    "timestamp" : 1542974400,
    "week" : "2018-47",
    "year" : "2018"
},
{
    "_id" : "1e33668e5528036752eb1304e8f9eb12",
    "account_id" : "5be43aa98ef5a748bb0b4fb2",
    "student" : {
        "_id" : "5be43ad18ef5a74a0c2767b1",
        "name" : "Jane doe",
        "gender" : "female",
        "status" : "1",
        "created_at" : false,
        "updated_at" : 1543494196
    },
    "student_id" : "5be43ad18ef5a74a0c2767b1",
    "var1" : 0,
    "cost" : 0,
    "day" : -1,
    "var2" : 0,
    "month" : -1,
    "timestamp" : -1,
    "week" : -1,
    "year" : -1
}

通过使用以下汇总查询:

db.getCollection('testing_collection').aggregate([
    {
        "$group": {
            "_id": {
                "student_id": "$student_id",
                "data1": "$data1"
            },
            "student": {
                "$max": "$student"
            },
            "var1": {
                "$sum": "$var1"
            },
            "var2": {
                "$sum": "$var2"
            },
            "cost": {
                "$sum": "$cost"
            }
        }
    }
    ,
    {
        "$project": {
            "_id": 0,
            "student_id": "$_id.student_id",
            "student_name": "$student.name",
            "data1": "$_id.data1",
            "var1": "$var1",
            "var2": "$var2",
            "cost": "$cost"
        }
    }
])

我可以将记录分组为: enter image description here

我正在寻找的是要获取的查询: -每行填充的student_name -根本不显示没有data1的第一条记录。

由于我正在使用分片集合,因此无法使用$ lookup。

这是一个用于报告的集合,由于性能的原因,我为每个学生创建了一条记录,并填写了“学生”数据。其他行仅包含student_id,并且每个学生都有数百万个条目。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我将结合使用facetunwind来模拟对同一表的查找:

db.testing_collection.aggregate([
    {
        "$group": {
            "_id": {
                "student_id": "$student_id",
                "data1": "$data1"
            },
            "student": {
                "$max": "$student"
            },
            "var1": {
                "$sum": "$var1"
            },
            "var2": {
                "$sum": "$var2"
            },
            "cost": {
                "$sum": "$cost"
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "student_id": "$_id.student_id",
            "student_name": "$student.name",
            "data1": "$_id.data1",
            "var1": "$var1",
            "var2": "$var2",
            "cost": "$cost"
        }
    },
    { "$facet": {
        "name" : [{ "$match": { "student_name": { "$exists": true } } } ],
        "data": [ { "$match": { "data1": { "$exists": true } } } ],
    } },
    { "$addFields": { "student": { "$arrayElemAt": [ "$name", 0 ] } } },
    { "$unwind": "$data"},    
    {
        "$project": {
            "_id": 0,
            "student_id": "$student.student_id",
            "student_name": "$student.student_name",
            "data1": "$data.data1",
            "var1": "$data.var1",
            "var2": "$data.var2",
            "cost": "$data.cost"
        }
    }
 ])

假设您每个学生ID都只有一个带有学生姓名的文档。

如果不是这种情况,并且有多个文档,则您可能希望将“名称”管道的“ $ match”阶段替换为“ $ group”以应用您的逻辑,而不是在下一阶段中选择第一个元素。

如果有没有带有学生姓名的文件的案例,则可能需要在“ $ addFields”阶段提供默认值。