得到" loglevel"为每个"名称"

时间:2016-06-21 07:37:04

标签: mongodb mongodb-query aggregation-framework

例如,我有以下集合:

  

db.names.find({})

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="xxxxxxxxxxxx">

<xsl:output method="xml" indent="yes"/>

<!-- ****************************************************************** -->
<xsl:template match="/">
    <xsl:apply-templates select="s3xml"/>
</xsl:template>

<!-- ****************************************************************** -->
<xsl:template match="/s3xml">
    <xsl:apply-templates select="./resource[@name='cap_alert']"/>
</xsl:template>

<!-- ****************************************************************** -->
<xsl:template match="resource[@name='cap_alert']">

    <alert>
        <identifier>
            <xsl:value-of select="data[@field='identifier']"/>
        </identifier>

        <sender>
            <xsl:value-of select="data[@field='sender']"/>
        </sender>

        <status>
            <xsl:value-of select="translate(data[@field='status']/@value, '&quot;', '')"/>
        </status>
        <incidents>??????</incidents>
    </alert>
</xsl:template>
</xsl:stylesheet>

我已经尝试了,但我认为它应该是更好的解决方案(也可以省略{ "_id" : ObjectId("5768d9b4bc6f464899594570"), "name" : "t1", "loglevel" : "ERROR" } { "_id" : ObjectId("5768d9d5bc6f464899594571"), "name" : "t1", "loglevel" : "ERROR" } { "_id" : ObjectId("5768d9dcbc6f464899594572"), "name" : "t1", "loglevel" : "WARNING" } { "_id" : ObjectId("5768d9dfbc6f464899594573"), "name" : "t1", "loglevel" : "WARNING" } { "_id" : ObjectId("5768d9e0bc6f464899594574"), "name" : "t1", "loglevel" : "WARNING" } { "_id" : ObjectId("5768d9e7bc6f464899594575"), "name" : "t1", "loglevel" : "INFO" } { "_id" : ObjectId("5768d9f3bc6f464899594576"), "name" : "t2", "loglevel" : "INFO" } { "_id" : ObjectId("5768d9f9bc6f464899594577"), "name" : "t2", "loglevel" : "ERROR" } { "_id" : ObjectId("5768da19bc6f464899594578"), "name" : "t2", "loglevel" : "ERROR" } { "_id" : ObjectId("5768da1abc6f464899594579"), "name" : "t2", "loglevel" : "ERROR" } { "_id" : ObjectId("5768da1bbc6f46489959457a"), "name" : "t2", "loglevel" : "ERROR" } { "_id" : ObjectId("5768e247bc6f46489959457b"), "name" : "t3", "loglevel" : "INFO" }

else

2 个答案:

答案 0 :(得分:3)

删除{ "$sum": 1 }条件块中的{ "$sum": 0 }if/else表达式,将值替换为值1和0(分别针对每个条件块)。

最终的管道应如下所示,使用其他 $cond 语法省略if/else块:

db.names.aggregate([
    {
        "$group": {
            "_id": "$name",
            "error": { 
               "$sum": { 
                   "$cond": [ { "$eq": [ "$loglevel",  "ERROR" ] }, 1, 0] 
               }
           },
           "warning":{
               "$sum": { 
                   "$cond": [ { "$eq": [ "$loglevel", "WARNING" ] }, 1, 0 ]
                }
           },
           "info": { 
               "$sum": { 
                   "$cond": [ { "$eq": [ "$loglevel",  "INFO" ] }, 1, 0 ]
               }
           }
        }
    }
])

或者在给定一系列可能的状态的情况下动态创建管道:

var statuses = ["ERROR", "WARNING", "INFO"],
    groupOperator = { "$group": { "_id": "$name" } };

statuses.forEach(function (status){ 
    groupOperator["$group"][status.toLowerCase()] = { 
       "$sum": { 
           "$cond": [ { "$eq": [ "$loglevel",  status ] }, 1, 0] 
       }
   }
});

db.names.aggregate([groupOperator]);

<强>输出

/* 1 */
{
    "_id" : "t1",
    "error" : 2,
    "warning" : 3,
    "info" : 1
}

/* 2 */
{
    "_id" : "t2",
    "error" : 4,
    "warning" : 0,
    "info" : 1
}

/* 3 */
{
    "_id" : "t3",
    "error" : 0,
    "warning" : 0,
    "info" : 1
}

答案 1 :(得分:1)

如果我理解正确,您需要针对每个名称的loglevel之和。 这不应该有帮助吗?

   db.names.aggregate([{$group:{_id:{name:"$name",loglevel:"$loglevel"},sum:{$sum:1}}}])