我有一个收集学生的文件,格式如下: -
{
_id:"53fe74a866455060e003c2db",
name:"sam",
subject:"maths",
marks:"77"
}
{
_id:"53fe79cbef038fee879263d2",
name:"ryan",
subject:"bio",
marks:"82"
}
{
_id:"53fe74a866456060e003c2de",
name:"tony",
subject:"maths",
marks:"86"
}
我想得到所有学生的总分数= subject =“maths” . 所以我应该得到163总和 .
db.students.aggregate([{ $match : { subject : "maths" } },
{ "$group" : { _id : "$subject", totalMarks : { $sum : "$marks" } } }])
现在我应该得到以下结果 -
{"result":[{"_id":"53fe74a866455060e003c2db", "totalMarks":163}], "ok":1}
但我得到 -
{"result":[{"_id":"53fe74a866455060e003c2db", "totalMarks":0}], "ok":1}
有人能指出我在这里做错了什么吗?
2 回答
您当前的架构将
marks
字段数据类型作为字符串,您需要一个整数数据类型供您的聚合框架计算总和 . 另一方面,您可以使用MapReduce来计算总和,因为它允许在 Map 函数的对象属性上使用parseInt()
等本机JavaScript方法 . 总的来说,你有两个选择 .选项1:更新架构(更改数据类型)
第一种方法是更改架构或在文档中添加具有实际数值而不是字符串表示的另一个字段 . 如果您的集合文档大小相对较小,您可以使用mongodb的游标 find() , forEach() 和 update() 方法的组合来更改标记架构:
对于相对较大的集合大小,您的数据库性能会很慢,建议使用mongo bulk updates:
MongoDB versions >= 2.6 and < 3.2:
MongoDB version 3.2 and newer:
选项2:运行MapReduce
第二种方法是使用MapReduce重写您的查询,您可以使用JavaScript函数
parseInt()
.在MapReduce操作中,定义处理每个输入文档的map函数 . 此函数将转换后的
marks
字符串值映射到每个文档的subject
,并发出subject
并转换marks
对 . 这是可以应用JavaScript本机函数parseInt()
的地方 . 注意:在函数中,this
指的是map-reduce操作正在处理的文档:接下来,使用两个参数
keySubject
和valuesMarks
定义相应的reduce函数 .valuesMarks
是一个数组,其元素是map函数发出的整数marks
值,并按keySubject
分组 . 该函数将valuesMarks
数组缩减为其元素之和 .通过您的集合,上面将把您的MapReduce聚合结果放入一个新的集合
db.example_results
中 . 因此,db.example_results.find()
将输出:返回0的可能原因是:
Make sure the field contains numeric values.
在指定字段名称时使用引号内的空格或制表符 .
示例 - "$price " won't work !!! 但是, "$price" would work.