【问题标题】:How to group-by results of survey in mongodb and mongoose?如何在 mongodb 和 mongoose 中对调查结果进行分组?
【发布时间】:2016-01-05 22:00:13
【问题描述】:

我的应用中有一个动作集合,它具有以下对象结构:

    {
        "type" : "evMove",
        "userId" : "55fbbb2a34d594085988aa70",
        "data" : {
            "evId"   : "55fdaa53cca301f758f4023d",
            "moveId" : "55fdaa53cca301f758f4023f"
        }
    },
    {
        "type" : "game",
        "userId" : "55fgdfa34d594085988aa70",
        "data" : {
            ...
        }
    },
    {
        "type" : "evMove",
        "userId" : "55fbbb2aasd34d595988aa60",
        "data" : {
            "evId"   : "55fdaa53cca301f758f4023d",
            "moveId" : "55fdaa53cca301f758f4023f"
        }
    },
{
        "type" : "evMove",
        "userId" : "55fbbb2a34d594085988aa30",
        "data" : {
            "evId"   : "55fdaa53cca301f758f4023d",
            "moveId" : "55fdaa53cca301f758f4023g"
        }
    }

我需要在 mongodb 和 mongoose 中返回一个返回以下内容的结果:

 for event id: 55fdaa53cca301f758f4023d

  moveId:55fdaa53cca301f758f4023d, count:2
  moveId:55fdaa53cca301f758f4023g, count:1

如果我在 javascript 中执行此操作并且没有 group by like 查询,这意味着以下内容:

db.actions.find({'type':'evMove','data.evId':'55fdaa53cca301f758f4023d'})

 resultArray = {
       55fdaa53cca301f758f4023d : 0,
       55fdaa53cca301f758f4023g : 0
    };
    results.forEach(function(res){
         resultArray[res.data.evMove]++;
    );

我怎样才能在 mongodb 和 mongoose 中或多或少地为我提供我想要的结果(移动和计数)?

【问题讨论】:

  • 那你想要什么?它是每个不同 evId 值的不同 moveId 值的计数吗?
  • 是的!就你所说的,它将在我的查询中更具体,这意味着,仅适用于一个 evId,而不适用于我的所有操作表 evIds...
  • 我有一个 evId,为此我假设有 4 个选项供用户选择(moveId),我只想计算有多少用户选择了一个动作而不是另一个动作,仅用于一个一次 evId

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

你想要.aggregate() 可以在指定的键上“分组”。起初你对两者进行分组,虽然不完全按照你要求的格式,但第二个 $group 将结果“汇总”到一个数组中:

Model.aggregate([
    { "$match": {
        "type": "evMove",
        "data.evId": new ObjectId("55fdaa53cca301f758f4023d")
    }},
    { "$group": {
        "_id": {
            "evId": "$data.evId",
            "moveId": "$data.moveId"
        },
        "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": "$_id.evId",
        "moves": {
            "$push": { 
                "moveId": "$_id.moveId",
                "count": "$count"
            }
        }
    }}
],function(err,results) {
    // results in here
});

这会给你这样的结果:

{ 
    "_id": "55fdaa53cca301f758f4023d",
    "moves": [
        { "moveId": "55fdaa53cca301f758f4023d", "count": 2 }
        { "moveId": "55fdaa53cca301f758f4023g", "count": 1 }
    ]

}

另请注意,如果您希望这用于“多个”eventId 值,则只需从 $match 中删除该行。

当然,由于聚合管道不执行 mongoose 在其他 .find() 类型操作(基于模式)中所做的“自动转换”,因此您需要自己“转换”类型。因此来自核心驱动程序的ObjectId 方法。但这仅在您需要将内容 $match 设置为这样的 _id 值时才需要,因为所有其他评估都在管道本身内部。

【讨论】:

    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多