Группировать по полю документа из встроенного массива, затем по полю родительского документа

Я не уверен, как это сформулировать, но в основном я хочу сгруппировать документы по полю из дочернего массива, затем я хочу сгруппировать по полю в родительском (корневом) документе, но сохранив предыдущую группировку.

Я надеюсь, что пример поможет здесь.

Допустим, у меня есть эти документы, где информация о нескольких custItemNum почти сгруппированы по originalFile:

[
    {
        "items" : [ 
            {
                "recType" : "I2",
                "qty" : 2.0,
                "custItemNum" : 10.0
            }, 
            {
                "recType" : "I2",
                "qty" : 200.0,
                "custItemNum" : 20.0
            }, 
            {
                "recType" : "I2",
                "qty" : 50.0,
                "custItemNum" : 30.0
            }, 
            {
                "recType" : "D9",
                "custItemNum" : 10.0
            }, 
            {
                "recType" : "D9",
                "custItemNum" : 20.0
            }, 
            {
                "recType" : "D9",
                "custItemNum" : 30.0
            }
        ],
        "originalFile" : "727451921.txt",
        "docId" : "278791399"
    },
    {
        "items" : [ 
            {
                "recType" : "I2",
                "qty" : 180.0,
                "custItemNum" : 20.0
            }
        ],
        "originalFile" : "727557371.txt",
        "docId" : "278791399"
    },
    {
        "items" : [ 
            {
                "recType" : "I2",
                "qty" : 10.0,
                "custItemNum" : 30.0
            }
        ],
        "originalFile" : "727557371.txt",
        "docId" : "278791399"
    },
    {
        "items" : [ 
            {
                "recType" : "I2",
                "qty" : 10.0,
                "custItemNum" : 30.0
            }
        ],
        "originalFile" : "727557371.txt",
        "docId" : "278791399"
    }
]

Я хочу закончить с такой коллекцией, где первая группировка по custItemNumber а затем originalFile:

[
    {
        "custItemNumber" : 10.0,
        "count" : 2.0,
        "itemInfo" : [ 
            {
                "originalFile" : "727451921.txt",
                "item" : [ 
                    {
                        "recType" : "I2",
                        "qty" : 2.0,
                        "custItemNum" : 10.0
                    }, 
                    {
                        "recType" : "D9",
                        "custItemNum" : 10.0
                    }
                ]
            }
        ]
    },
    {
        "custItemNumber" : 20.0,
        "count" : 3.0,
        "itemInfo" : [ 
            {
                "originalFile" : "727451921.txt",
                "item" : [ 
                    {
                        "recType" : "I2",
                        "qty" : 200.0,
                        "custItemNum" : 20.0
                    }, 
                    {
                        "recType" : "D9",
                        "custItemNum" : 20.0
                    }
                ]
            }, 
            {
                "originalFile" : "727557371.txt",
                "item" : [ 
                    {
                        "recType" : "I2",
                        "qty" : 180.0,
                        "custItemNum" : 20.0
                    }
                ]
            }
        ]
    },
    {
        "custItemNumber" : 30.0,
        "count" : 4.0,
        "itemInfo" : [ 
            {
                "originalFile" : "727451921.txt",
                "item" : [ 
                    {
                        "recType" : "I2",
                        "qty" : 50.0,
                        "custItemNum" : 30.0
                    }, 
                    {
                        "recType" : "D9",
                        "custItemNum" : 30.0
                    }
                ]
            }, 
            {
                "originalFile" : "727557371.txt",
                "item" : [ 
                    {
                        "recType" : "I2",
                        "qty" : 10.0,
                        "custItemNum" : 30.0
                    }, 
                    {
                        "recType" : "I2",
                        "qty" : 10.0,
                        "custItemNum" : 30.0
                    }
                ]
            }
        ]
    }
]

Имейте в виду, что эти документы уже состоят из нескольких этапов агрегирования, поэтому бесполезно _id поле доступно.

До сих пор я придумал эти этапы агрегирования (и вручную отредактировал его вывод, чтобы получить результат выше):

{$unwind: "$items"},
{$bucket: {
    groupBy: "$items.custItemNum",
    boundaries: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
    output: {
        count: {$sum: 1},
        itemInfo: {$push: "$$ROOT"}
    }
 }}

что приводит к такому результату:

[
    {
        "_id" : 10.0,
        "count" : 2.0,
        "itemInfo" : [ 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae528f"),
                "items" : {
                    "recType" : "I2",
                    "qty" : 2.0,
                    "custItemNum" : 10.0
                },
                "originalFile" : "727451921.txt",
                "docId" : "278791399"
            }, 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae528f"),
                "items" : {
                    "recType" : "D9",
                    "custItemNum" : 10.0
                },
                "originalFile" : "727451921.txt",
                "docId" : "278791399"
            }
        ]
    },
    {
        "_id" : 20.0,
        "count" : 3.0,
        "itemInfo" : [ 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae528f"),
                "items" : {
                    "recType" : "I2",
                    "qty" : 200.0,
                    "custItemNum" : 20.0
                },
                "originalFile" : "727451921.txt",
                "docId" : "278791399"
            }, 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae528f"),
                "items" : {
                    "recType" : "D9",
                    "custItemNum" : 20.0
                },
                "originalFile" : "727451921.txt",
                "docId" : "278791399"
            }, 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae5290"),
                "items" : {
                    "recType" : "I2",
                    "qty" : 180.0,
                    "custItemNum" : 20.0
                },
                "originalFile" : "727557371.txt",
                "docId" : "278791399"
            }
        ]
    },
    {
        "_id" : 30.0,
        "count" : 4.0,
        "itemInfo" : [ 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae528f"),
                "items" : {
                    "recType" : "I2",
                    "qty" : 50.0,
                    "custItemNum" : 30.0
                },
                "originalFile" : "727451921.txt",
                "docId" : "278791399"
            }, 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae528f"),
                "items" : {
                    "recType" : "D9",
                    "custItemNum" : 30.0
                },
                "originalFile" : "727451921.txt",
                "docId" : "278791399"
            }, 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae5291"),
                "items" : {
                    "recType" : "I2",
                    "qty" : 10.0,
                    "custItemNum" : 30.0
                },
                "originalFile" : "727557371.txt",
                "docId" : "278791399"
            }, 
            {
                "_id" : ObjectId("5a7336ebb4b169272dae5292"),
                "items" : {
                    "recType" : "I2",
                    "qty" : 10.0,
                    "custItemNum" : 30.0
                },
                "originalFile" : "727557371.txt",
                "docId" : "278791399"
            }
        ]
    }
]

Я застрял здесь, любой другой шаг, который приходит на ум (т.е. $replaceRoot : { newRoot: "$itemInfo" }) сломал бы внешнюю группировку.

Плюс custItemNum значения являются динамическими, но AFAICT boundaries поле $bucket Этап принимает постоянный массив, поэтому, если есть способ передать вычисляемый массив туда, я хотел бы знать, как.

0 ответов

Вы можете попробовать ниже этапов агрегации.

[
   {"$unwind":"$items"},
   {"$sort":{"originalFile":1}},
   {"$group":{_id:"$items.custItemNum","count":{"$sum":1},"itemInfo":{"$push":{"originalFile":"$originalFile","items":"$items"}}}},
   {"$sort":{"_id":1}}
]
Другие вопросы по тегам