Условная группа в mongodb - PullRequest
       5

Условная группа в mongodb

0 голосов
/ 03 декабря 2018

У меня есть коллекция, которая содержит такие данные, как:

{
    "_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

Мне нужен запрос: - имя студента, заполненное для каждой строки - вообще не показывать первую запись, в которой нет данных1.

Я не могу использовать $ lookup, так как я работаю с закрытыми коллекциями.

Это коллекция, которая используется для составления отчетов, и по соображениям производительности у меня есть одна запись для каждого учащегося с заполненными данными "ученика". Другие строки содержат только student_id и будут иметь миллионы записей длякаждый студент.

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 03 декабря 2018

Я бы использовал комбинацию facet и unwind для эмуляции поиска по одной и той же таблице:

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"
        }
    }
 ])

Предполагается, что у вас ровно 1 документ с именем студентадля каждого student_id.

Если это не так, и существует более 1 документа, вы можете заменить этап «$ match» конвейера «name» на «$ group», чтобы применить свою логику вместо выбора первого элемента вследующий этап.

Если есть случаи, когда нет документов с именем студента, вы можете указать значения по умолчанию на этапе "$ addFields".

...