我们如何在MongoDB聚合查询中对各个数组元素求和?

时间:2016-10-25 08:00:19

标签: php mongodb mongodb-query aggregation-framework

Document :
  {
    "version": "1.0.0",
    "actor": {
        "objectType": "Agent",
        "name": "Test user",
        "account": {
            "homePage": "http://testing.com/",
            "name": "67"
        }
    },
    "verb": {
        "id": "http://adlnet.gov/expapi/verbs/completed",
        "display": {
            "en-US": "completed"
        }
    },
    "object": {
        "objectType": "Activity",
        "id": "http://localhost/action?id=cji",
        "definition": {
            "type": "http://adlnet.gov/expapi/activities/lesson",
            "name": {
                "en-US": "ps3"
            },
            "description": {
                "en-US": "ps3"
            }
        }
    },
    "timestamp": "2016-10-25T11:21:25.917Z",
    "context": {
        "extensions": {
            "http://localhost/eventinfo": {
                "sessionId": "1477393533327",
                "starttm": "1477394351210",
                "eventtm": "1477394485917",
                "course": "cji"
            }
        },
        "contextActivities": {
            "parent": [
                {
                    "objectType": "Activity",
                    "id": "http://localhost/id=cji"
                }
            ]
        }
    },
    "result": {
        "duration": "PT2M14.71S",
        "score": {
            "raw": 6,
            "max": 21
        }
    },
    "authority": {
        "objectType": "Agent",
        "name": "New Client",
        "mbox": "mailto:hello@lhd.net"
    },
    "stored": "2016-10-25T11:20:29.666700+00:00",
    "id": "c7039783-371f-4f59-a665-65a9d09a2b7f"
}

We've got this PHP + MongoDB aggregation query:

    $condition = array(
                 array(
                '$match' => array(
                    'client_id' => $CFG->mongo_clientid,
                    'statement.actor.account.name' => array('$in'=> array('67','192','213')),
                    'statement.verb.id' => 'http://adlnet.gov/expapi/verbs/completed',
                    'statement.object.id' => 'http://localhost/action?id=cji'
                )),
                 array(
                '$group' => array(
                    '_id' =>  '$statement.actor.account.name' ,
                    //'totalpoints' =>array( '$sum' => array('$last' => '$statement.result.score.raw'))                
                    'laststatement' => array('$last' => '$statement.result.score.raw'),
                    //'sumtest' => array('$add' => ['$laststatement'])
                     )
                  )
            );
             $cursor = $collection->aggregate($condition);
             echo "
";
             print_r($cursor);
             echo "
"; which returns this result: Array ( [result] => Array ( [0] => Array ( [_id] => 192 [laststatement] => MongoInt64 Object ( [value] => 4 ) ) [1] => Array ( [_id] => 67 [laststatement] => MongoInt64 Object ( [value] => 6 ) ) ) [ok] => 1 )

我们如何在MongoDB聚合查询中对这些单个数组元素的[laststatement].[value]求和?

";
             print_r($cursor);
             echo "

另外,我们如何在MongoDB聚合查询中一起使用[laststatement] => MongoInt64 Object ( [value] => values goes here ) $last? 在我的结果中,2个不同的id(192,67)有2个原始分数(最后一个语句)。对于所有多个id,我想总结这个分数,如4 + 6 = 10,但只想要最后一个语句的最后得分。我无法在线上使用$ last和$ sum。请检查

1 个答案:

答案 0 :(得分:2)

看起来你想要的只是一个组。因此分组ID应为null。如果您关心最后一条记录,您可能需要添加排序。未经测试。

array(
      '$group' => array(
      '_id' =>  null ,
      'totalpoints' => array( '$sum' => '$statement.result.score.raw')                
      'laststatement' => array('$last' => '$statement.result.score.raw')
     )
)

这是mongo shell版本。

aggregate([
    {
       $match :{
             "actor.account.name":{$in:["67","192","213"]},
             "verb.id":{$eq:"http://adlnet.gov/expapi/verbs/completed"},
             "object.id":{$eq:"http://localhost/action?id=cji"}
       }
    },
    {
      $group: {
          "_id": null,
          "totalpoints" : {$sum:"$result.score.raw"},                
          "laststatement" :{$last:"$result.score.raw"}
      }
    }
])

输出:

{ "_id" : null, "totalpoints" : 10, "laststatement" : 4 }

更新已更改为包含每个组中最后一个语句的总和。第一个分组是按actor名称,并返回每个组的最后一个语句。第二个分组总结了最后一个陈述。

aggregate([{
    $match: {
        "actor.account.name": {
            $in: ["67", "192", "213"]
        },
        "verb.id": {
            $eq: "http://adlnet.gov/expapi/verbs/completed"
        },
        "object.id": {
            $eq: "http://localhost/action?id=cji"
        }
    }
}, {
    $group: {
        "_id": "$actor.account.name",
        "laststatement": {
            $last: "$result.score.raw"
        }
    }
}, {
    $group: {
        "_id": null,
        "totalpoints": {
            $sum: "$laststatement"
        },
    }
}])