假设我有这样的文件:
filter:
我想计算集合中答案记录的数量。显然,该文件提供了两个答案记录,即“1”和“3”。所以,我的问题是如何使用聚合管道来实现这一点。
答案 0 :(得分:1)
对于MongoDB 3.6及更高版本,请使用聚合管道中的$objectToArray
运算符将文档转换为数组。返回数组包含原始文档中每个字段/值对的元素。返回数组中的每个元素都是包含两个字段k
和v
的文档。
在获取数组时,您可以利用$addFields
管道步骤创建一个包含计数的字段,并使用 $size
<派生实际计数/ strong>运营商。
所有这些都可以通过嵌套表达式在单个管道中完成:
db.collection.aggregate([
{
"$addFields": {
"answers_count": {
"$size": {
"$objectToArray": "$answer_records"
}
}
}
}
])
示例输出
{
"_id" : ObjectId("57eb386e37b4842ff5f386c9"),
"lesson_id" : ObjectId("57e27cd190e6993e393f5c74"),
"student_id" : ObjectId("57d3c3f590e6995fe8de7932"),
"answer_records" : {
"1" : {
"answer" : [
"A"
]
},
"3" : {
"answer" : [
"C"
]
}
},
"answers_count": 2
}
对于不支持上述运算符的MongoDB服务器版本,您需要更改架构设计,以便使用聚合框架执行高效查询。因为它是你现在所需要的 使用JavaScript在客户端或服务器上预处理文档,因此您无法充分利用MongoDB为更快查询而构建的更好的基础架构。
理想的设计如下:
{
"_id" : ObjectId("57eb386e37b4842ff5f386c9"),
"lesson_id" : ObjectId("57e27cd190e6993e393f5c74"),
"student_id" : ObjectId("57d3c3f590e6995fe8de7932"),
"answer_records" : [
{ "id": "1", "answer": "A" }
{ "id": "3", "answer": "C" }
]
}
然后您可以简单地应用聚合的 $project
管道,该管道使用 $size
运算符来返回每个文档的answer_records数组:
db.collection.aggregate([
{
"$project": {
"lesson_id": 1,
"student_id": 1,
"count": { "$size": "$answer_records" }
}
}
])
如果您想要整个集合的答案记录总数,请添加另一个 $group
管道,以使用_id为null获取所有文档的累计总数:
db.collection.aggregate([
{
"$project": {
"count": { "$size": "$answer_records" }
}
},
{
"$group": {
"_id": null,
"total_answers": { "$sum": "$count" }
}
}
])
否则,对于当前设计,您唯一的选择是MapReduce,它要慢得多:
db.collection.mapReduce(
function() {
emit(this._id, Object.keys(this.answer_records).length);
},
function() { },
{ "out": { "inline": 1 } }
)
示例输出:
{
"results" : [
{
"_id" : ObjectId("57eb386e37b4842ff5f386c9"),
"value" : 2
}
],
....
}
要获取集合中所有文档的总数,请运行此mapReduce操作:
db.collection.mapReduce(
function() {
emit(null, Object.keys(this.answer_records).length);
},
function(key, values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
答案 1 :(得分:1)
在您的情况下,使用JS要容易得多。
在mongo shell上:
var json=db.sof.findOne().answer_records;
Object.keys(json).length;
打印2表示上述文件中的答案记录数。