【问题标题】:MongoDB: Calculate average of all the specific document's field which are embedded as list in a documentMongoDB:计算作为列表嵌入文档中的所有特定文档字段的平均值
【发布时间】:2014-01-06 08:28:06
【问题描述】:

这里是mongodb中文档的结构:

{
    "_id" : NumberLong(1),
    "averageRating" : 2.5,
    "date" : ISODate("2013-11-12T02:15:14.448Z"),
    "filledBy" : "Degroote, Fred",
    "results" : [
        {
            "answer" : "Very caring doctor. I am happy",
            "name" : "comment",
            "type" : "string"
        },
        {
            "answer" : "4",
            "name" : "premises",
            "type" : "integer"
        },
        {
            "answer" : "5",
            "name" : "staff",
            "type" : "integer"
        },
        {
            "answer" : "0",
            "name" : "provider",
            "type" : "integer"
        },
        {
            "answer" : "1",
            "name" : "care",
            "type" : "integer"
        }
    ],
    "tenantId" : NumberLong(2),
    "token" : "38ae01f0-1203-4d10-9ff1-7c9fad1790cc",
    "version" : NumberLong(0)
}

我们需要计算所有tenantId值为2的文档结果中结果名称“staff”的答案得分的平均值。

我们写的mongodb查询是:

> db.surveyResults.aggregate({$match: {'tenantId': 2}}, {$unwind: '$results'}, {$match: {'results.type':'integer'}},{$group: {_id: '$results.name', averageSatisfaction: {$avg: '$results.answer'}}})

但是,上述 mongodb 查询中的问题是字段 answer 是字符串类型。有什么方法可以在不改变字段答案类型的情况下解决这个问题?

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    我认为这是一个丑陋的查询,但它有效:

    db.surveyResults.aggregate(
        {$match: {'tenantId': 2}}, 
        {$unwind: '$results'}, 
        {$match: {'results.type':'integer'}},
        {$project:{
            "results.answer":1,
            "results.name":1,
            one:{$cond:[{$eq:["$results.answer","1"]},1,0]},
            two:{$cond:[{$eq:["$results.answer","2"]},2,0]},
            three:{$cond:[{$eq:["$results.answer","3"]},3,0]},
            four:{$cond:[{$eq:["$results.answer","4"]},4,0]},
            five:{$cond:[{$eq:["$results.answer","5"]},5,0]},
            six:{$cond:[{$eq:["$results.answer","6"]},6,0]},
            seven:{$cond:[{$eq:["$results.answer","7"]},7,0]},
            eight:{$cond:[{$eq:["$results.answer","8"]},8,0]},
            nine:{$cond:[{$eq:["$results.answer","9"]},9,0]},
            }  
        },
        {$project: {
            "results.name":1,         
            sum:{$add:["$one","$two","$three","$four","$five","$six","$seven","$eight","$nine"]}        
         }},
         {$group: 
             {_id: '$results.name', averageSatisfaction: {$avg: '$sum'}}
    
    
            }
    
           )
    

    无论如何,最好的选择是使用整数作为整数。

    【讨论】:

    • 我们通过不计算平均值找到了替代方案。相反,按名称对所有答案进行分组,然后在外部计算平均值。这是我们正在使用的查询: > db.surveyResults.aggregate({$match: {'tenantId': 2}}, {$project:{'results':1}},{$unwind: '$results'} , {$match: {'results.type':'integer'}},{$group: {_id: '$results.name', 答案: {$push: '$results.answer'}}})跨度>
    • 很高兴您找到了解决方法。也许我的解决方案可以帮助其他人。
    猜你喜欢
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    相关资源
    最近更新 更多