Unable to compute average time

我们两清 提交于 2019-12-25 07:47:46

问题


3 days old into MongoDB, and I am not finding it very fluid. I am simply trying to compute the average time for a field but I keep running into all sorts of problems.

Here is my code:

db.results.group({
     key:{"profile.Zend_Http_Client_Adapter_Socket::read==>fgets":{$exists:true}},
     initial: {count: 0, total:0},
     reduce: function(doc, out){ 
         out.count++; 
         out.total += doc."profile.Zend_Http_Client_Adapter_Socket::read==>fgets.wt";
     },
     finalize: function(out){
            out.avg = out.total/out.count;
     }
});

The error:

SyntaxError: Unexpected String

The above is a very childish error, but I can't understand why it would state this, the only plausible reason I can think of is that the keys I have specified here are in quotes hence Mongo is getting confused.

BUT, these keys ARE in quotes in my collection, so there should be no reason why I keep getting this syntax error right ?

Sample document:

{
    "_id" : ObjectId("532a2a986803faba658b456b"),
    "profile" : {
        "main()==>register_shutdown_function" : {
            "ct" : 1,
            "wt" : 13,
            "cpu" : 0,
            "mu" : 1568,
            "pmu" : 1000
        },
        "main()==>load::htdocs/index.php" : {
            "ct" : 1,
            "wt" : 17,
            "cpu" : 0,
            "mu" : 1736,
            "pmu" : 4296
},
        {"Zend_Http_Client_Adapter_Curl::write==>curl_exec" : {                                           
            "ct" : 3,
            "wt" : 54782314,
            "cpu" : 16001,
            "mu" : 83288,
            "pmu" : 49648
        }, ....

回答1:


As per the comment your problem is one of forming valid JavaScript. Also your "key" value would not seem to be what you really want. There is however the aggregate function that you should be favoring over the use of "group"

db.results.aggregate([
    { "$match": {
        "$and": [
            { "profile.Zend_Http_Client_Adapter_Socket::read==>fgets.wt": {
                "$exists": true 
            }},
            { "profile.Zend_Http_Client_Adapter_Socket::read==>fgets.wt": { 
               "$not": { "$type": 2 }
            }}
        ]
    }},
    { "$group": {
        "_id": null,
        "total": { "$sum": 
            "$profile.Zend_Http_Client_Adapter_Socket::read==>fgets.wt"
        },
        "count": { "$sum": 1 }
    }},

    { "$project": {
        "_id": 0,
        "avg": { "$divide": [ "$total", "$count" ] }
   }}
])

The aggregation pipeline sort of supercedes earlier introduced functions such as group and distinct. And for all but trivial operations should be your favored choice.

It will run much faster as well as this is processed in native code and not the JavaScript engine.

Also see the SQL to aggregation mapping chart in the documentation.

Problems With Data

Your sample is not very complete. To sort out all issues I have to put in a document like this:

{
    "profile": {
        "Zend_Http_Client_Adapter_Socket::read==>fgets": {                                           
            "ct" : 3,
            "wt" : 54782314,
            "cpu" : 16001,
            "mu" : 83288,
            "pmu" : 49648
        },
    }
}

Also your document example has some invalid fields in it:

{
    "_id" : ObjectId("532a2a986803faba658b456b"),
    "profile" : {
        "main()==>register_shutdown_function" : {
            "ct" : 1,
            "wt" : 13,
            "cpu" : 0,
            "mu" : 1568,
            "pmu" : 1000
        },
        "main()==>load::htdocs/index.php" : { <-- Invalid
            "ct" : 1,
            "wt" : 17,
            "cpu" : 0,
            "mu" : 1736,
            "pmu" : 4296
},

So that field cannot exist as it has a . in the field name, which for obvious sub-document reasons is not allowed.




回答2:


@Neils answer led me to the correct solution:

db.results.aggregate([
    {
       $match: {
            "profile.Zend_Http_Client_Adapter_Socket::read==>fgets.wt": {
                "$exists": true
            }
        }
    },
    {
        $group: {
            "_id": null,
            "total": {
                $sum: "$profile.Zend_Http_Client_Adapter_Socket::read==>fgets.wt"
            },
            "count": {
                $sum: 1
            }
        }
    },
    {
        $project: {
            "_id": 0,
            "count": "$count",
            "avg": {
                $divide: [
                    "$total",
                    "$count"
                ]
            }
        }
    }
]);


来源:https://stackoverflow.com/questions/22585134/unable-to-compute-average-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!