如何在mongoDB中的每个组和前N的其他字段中进行分组并获得前N个

时间:2017-08-21 19:30:31

标签: mongodb mongodb-query database

我有以下文件:

{
    "_id" : ObjectId("599b1a789125130dfc613188"),
    "traj_id" : 1,
    "aisle_id" : "Aisle01",
    "traf_seq" : [ 
        {
            "node" : "catg1",
            "pst" : 1,
            "time" : 12.0
        }, 
        {
            "node" : "catg2",
            "pst" : 2,
            "time" : 12.0
        }
    ]
},
{
    "_id" : ObjectId("599b1a789125130dfc613188"),
    "traj_id" : 2,
    "aisle_id" : "Aisle01",
    "traf_seq" : [ 
        {
            "node" : "catg1",
            "pst" : 1,
            "time" : 12.0
        }, 
        {
            "node" : "catg2",
            "pst" : 2,
            "time" : 12.0
        },
        {
            "node" : "catg1",
            "pst" : 1,
            "time" : 12.0
        }, 
    ]
},
{
    "_id" : ObjectId("599b1a789125130dfc613188"),
    "traj_id" : 3,
    "aisle_id" : "Aisle02",
    "traf_seq" : [ 
        {
            "node" : "catg1",
            "pst" : 1,
            "time" : 12.0
        }, 
        {
            "node" : "catg2",
            "pst" : 2,
            "time" : 12.0
        },
        {
            "node" : "catg2",
            "pst" : 3,
            "time" : 12.0
        }, 
    ]
}

我正在尝试在每个过道中访问的前N个类别。比如N = 1, 预期的输出将是:

"_id" : {
    "aisle" : "Aisle01",
    "catg" : "catg1"
},
"maxValue" : 3.0


"_id" : {
    "aisle" : "Aisle02"
    "catg" : "catg2"

},
"maxValue" : 2.0

由于在过道1中,catg 1已被访问过最多次数(即3次),而过道中的catg2已被访问过2次(最大值)。

我可以在每个过道中获得最大数量,但我很难获得类别名称,因为我在group by字段中将其排除。 或者我得到所有类别的名称,这是我不想要的。 以下是我到目前为止:

db.test.aggregate([
{$unwind:"$traf_seq"},
{$group: {
"_id": {
    "traj_id" :"$traj_id",
    "node": "$traf_seq.node",
    "aisle":"$aisle_id"
},
"count":{
    "$sum":1}
}},
{$group: {
"_id": {
    "sumnode":"$_id.node",
    "aisle": "$_id.aisle"},
"distcount":{
    "$sum":1},
}},
{$group: {
"_id": {
     "aisle": "$_id.aisle"},
     "otherField1":{$push:"$_id.sumnode"},        
"maxValue": {$max:"$distcount"}
}}

1 个答案:

答案 0 :(得分:0)

对于N = 1,以下应该可以解决问题:

db.test.aggregate([
    { $unwind: "$traf_seq" },
    {
        $group: {
            "_id": {
                "aisle": "$aisle_id",
                "node": "$traf_seq.node"
            },
            "maxvalue": { $sum: 1 }
        }
    },
    {
        $sort: {
            "maxvalue": -1
        }
    },
    {
        $group: {
            "_id": "$_id.aisle",
            "maxvalue": { $first: "$maxvalue" },
            "catg": { $first: "$_id.node" }
        }
    }
])

如果您需要不同的输出结构,可以使用$project来实现。如果是这样的话,请告诉我......

对于任意N,以下内容应该让您开始:

db.test.aggregate([
    { $unwind: "$traf_seq" },
    {
        $group: {
            "_id": {
                "aisle": "$aisle_id",
                "node": "$traf_seq.node"
            },
            "maxvalue": { $sum: 1 }
        }
    },
    {
        $sort: {
            "maxvalue": -1
        }
    },
    {
        $group: {
            "_id": "$_id.aisle",
            "docs": {
                $push: {
                    "maxvalue": "$maxvalue",
                    "catg": "$_id.node"
                }
            }
        }
    },
    {
        $project:
        {
            docs: {
                $slice:
                [
                    "$docs",
                    2 // this is where you can configure you N records
                ]
            }
        }
    },
    { $unwind: "$docs" }
])