MongoDB$reduce(聚合)组,包含数组中嵌套文档的总和,并按组计数

MongoDB$reduce(聚合)组,包含数组中嵌套文档的总和,并按组计数,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,MongoDB聚合框架查询:$group、$project、$addFields和$reduce 用例:我在集合中有多个具有嵌套文档数组的文档,需要一个结果分组依据和每个分组项的总和作为累积量。另外,在年(日期)上设置match参数,如果年匹配,则只有该年文档应按和卷(嵌套文档数组)返回的总和进行分组 以下是收藏中的文件: { "_id": "1", "LSD": { "name": "TDL 05", "LSDNumber": "031"

MongoDB聚合框架查询:$group、$project、$addFields和$reduce

用例:我在集合中有多个具有嵌套文档数组的文档,需要一个结果分组依据和每个分组项的总和作为累积量。另外,在年(日期)上设置match参数,如果年匹配,则只有该年文档应按和卷(嵌套文档数组)返回的总和进行分组

以下是收藏中的文件:

{
    "_id": "1",
    "LSD": {
        "name": "TDL 05",
        "LSDNumber": "031"
    },
    "POD": [{           
            "Volume": 35.40,
            "VolUnit": "m3"
        },
        {           
            "Volume": 20.75,
            "VolUnit": "m3"
        },
        {
            "Volume": 15,
            "VolUnit": "m3"
        }
    ],
     "createdon": {
        "$date": "2014-08-02T18:49:17.000Z"
    }
},
{
    "_id": "2",
    "LSD": {
        "name": "Stock Watering",
        "LSDNumber": "01"
    },

    "POD": [{
            "Volume": 105,
            "VolUnit": "m3"
        },
        {
            "Volume": 70,
            "VolUnit": "m3"
        },
        {
            "Volume": 35,
            "VolUnit": "m3"
        }
    ],
     "createdon": {
        "$date": "2014-08-02T18:49:17.000Z"
    }
},
{
    "_id": "3",
    "LSD": {
        "name": "TDL 30 Stock Water",
        "LSDNumber": "030"
    },

    "POD": [{
        "Volume": 87,
        "VolUnit": "m3"
    }],
     "createdon": {
        "$date": "2019-08-02T18:49:17.000Z"
    }
},
{
    "_id": "4",
    "LSD": {
        "name": "TDL 30 Stock Water",
        "LSDNumber": "030"
    },
    "POD": [{
        "Volume": 25.12,
        "VolUnit": "m3"
    }],
     "createdon": {
        "$date": "2019-08-02T18:49:17.000Z"
    }
},
{
    "_id": "5",
    "LSD": {
        "name": "TDL 05",
        "LSDNumber": "031"
    },
    "POD": [
        {
            "Volume": 21,
            "VolUnit": "m3"
        }
    ],
     "createdon": {
        "$date": "2014-08-02T18:49:17.000Z"
    }
}
我有一个查询(C#Driver 2.0),按“LSD.LSDNumber”和“POD.Volume”之和分组。此处未添加匹配参数。这个很好用

查询:

{
    aggregate([{
        "$group": {
            "_id": "$LSD.LSDNumber",            
            "doc": {
                "$push": "$POD"
            },
            "data": {
                "$first": "$$ROOT"
            }
        }
    }, {
        "$addFields": {
            "LSDNumber": "$_id",            
            "GroupByDocCount": {
                "$size": "$doc"
            },
            "Cumulative": {
                "$reduce": {
                    "input": "$doc",
                    "initialValue": [],
                    "in": {
                        "$concatArrays": ["$$value", "$$this"]
                    }
                }
            }
        }
    }, {
        "$project": {
            "LSDNumber": 1,
            "GroupByDocCount": 1,           
            "CumulativeVol": {
                "$sum": "$Cumulative.Volume"
            }
        }
    }])
}
下面是结果

{    
    "LSDNumber":"031",
    "GroupByDocCount": 2,
    "CumulativeVol": 92.15
},
{    
    "LSDNumber":"030",
    "GroupByDocCount": 2,
    "CumulativeVol": 112.12
},
{    
    "LSDNumber":"01",
    "GroupByDocCount": 1,
    "CumulativeVol": 210
}
{    
    "LSDNumber":"031",
    "GroupByDocCount": 2,
    "CumulativeVol": 92.15,
    "Year": 2014
},
{    
    "LSDNumber":"01",
    "GroupByDocCount": 1,
    "CumulativeVol": 210,
    "Year": 2014
}
但是,我希望按照年份(在“createdon”日期)以及groupby(LSD.LSDNumber)和卷的总和(POD.volume)来获得文档匹配。 例如,如果是2014年,那么结果应该是贝娄

{    
    "LSDNumber":"031",
    "GroupByDocCount": 2,
    "CumulativeVol": 92.15
},
{    
    "LSDNumber":"030",
    "GroupByDocCount": 2,
    "CumulativeVol": 112.12
},
{    
    "LSDNumber":"01",
    "GroupByDocCount": 1,
    "CumulativeVol": 210
}
{    
    "LSDNumber":"031",
    "GroupByDocCount": 2,
    "CumulativeVol": 92.15,
    "Year": 2014
},
{    
    "LSDNumber":"01",
    "GroupByDocCount": 1,
    "CumulativeVol": 210,
    "Year": 2014
}
我尝试的查询总是不返回任何内容

{
    aggregate([{
        "$project": {
            "LSDNumber": 1,
            "GroupByDocCount": 1,
            "CumulativeVol": {
                "$sum": "$Cumulative.Volume"
            },
            "year": {
                "$year": "$data.createdon"
            }
        }
    }, {
        "$match": {
            "year": 2014
        }
    }, {
        "$group": {
            "_id": "$LSD.LSDNumber",
            "year": {
                "$first": "$year"
            },
            "doc": {
                "$push": "$POD"
            },
            "data": {
                "$first": "$$ROOT"
            }
        }
    }, {
        "$addFields": {
            "LSDNumber": "$_id",
            "yearCreate": "$year",
            "GroupByDocCount": {
                "$size": "$doc"
            },
            "Cumulative": {
                "$reduce": {
                    "input": "$doc",
                    "initialValue": [],
                    "in": {
                        "$concatArrays": ["$$value", "$$this"]
                    }
                }
            }
        }
    }])
}

这里出了什么问题。任何帮助都将不胜感激

您可以在
$addField
管道中添加年份变量,然后
$match

{
    "$group": {
        "_id": "$LSD.LSDNumber",            
        "doc": {
            "$push": "$POD"
        },
        "data": {
            "$first": "$$ROOT"
        }
    }
}, {
    "$addFields": {
        "LSDNumber": "$_id",            
        "GroupByDocCount": {
            "$size": "$doc"
        },
        "Cumulative": {
            "$reduce": {
                "input": "$doc",
                "initialValue": [],
                "in": {
                    "$concatArrays": ["$$value", "$$this"]
                }
            }
        },
        "Year": {
            "$year": "$data.createdon"
        }
    }
}, {
    "$match" : {"Year" : 2014}
}, {
    "$project": {
        "LSDNumber": 1,
        "GroupByDocCount": 1,           
        "CumulativeVol": {
            "$sum": "$Cumulative.Volume"
        },
        "Year" : "$Year"
    }
}
==结果===

/* 1 */
{
    "_id" : "01",
    "LSDNumber" : "01",
    "GroupByDocCount" : 1,
    "CumulativeVol" : 210,
    "Year" : 2014
}

/* 2 */
{
    "_id" : "031",
    "LSDNumber" : "031",
    "GroupByDocCount" : 2,
    "CumulativeVol" : 92.15,
    "Year" : 2014
}

有点晚了,但这是我的答案。我们只需要在最后阶段向管道中再添加一个项目阶段(额外)。然而,@Valijon的回答符合同样的要求

{
    aggregate([{
        "$project": {
            "LSDNumber": "$LSD.LSDNumber",
            "year": {
                "$year": "$createdon"
            },
            "PointOfDiversionVolumeDetails": 1
        }
    }, {
        "$match": {
            "year": 2014
        }
    }, {
        "$group": {
            "_id": "$LSDNumber",
            "doc": {
                "$push": "$PointOfDiversionVolumeDetails"
            }
        }
    }, {
        "$addFields": {
            "GroupByDocCount": {
                "$size": "$doc"
            },
            "Cumulative": {
                "$reduce": {
                    "input": "$doc",
                    "initialValue": [],
                    "in": {
                        "$concatArrays": ["$$value", "$$this"]
                    }
                }
            }
        }
    }, {
        "$project": {
            "CumulativeVol": {
                "$sum": "$Cumulative.Volume"
            },
            "LSDNumber": 1,
            "GroupByDocCount": 1
        }
    }, {
        "$sort": {
            "GroupByDocCount": -1
        }
    }])
}

为什么
“$year”:“$data.createdon”
中的
$data
在项目中?是否应该是
$createdon
?@DaveStSomeWhere抱歉,回复太晚了。无论如何,使用
$data.createdon
更正了
$createdon
,但结果相同。