我试图在Mongo中为每个文档计算子文档。
使用db.users.find().length()
在集合中轻松获取文档很容易。我想做类似db.users.projects.find().length()
的类似事情。我怎么能这样做?
编辑:
我想要的结果是知道每个用户有多少个项目...所以类似:
{_id: 123, projects: 4}
示例用户文档:
{
_id:{$oid: 123},
username: johnsmith,
projects: [{$oid: 456}, {$oid: 789}]
}
答案 0 :(得分:4)
Per @ n9code,您将需要聚合框架。但是,您可以使用$size
非常轻松地计算子文档:
db.users.aggregate([{
$project: {
_id: '$_id',
totalProjects: { $size: "$projects" }
}
}]);
哪个应该返回这样的内容:
{ "_id" : ObjectID(...), "totalProjects" : 89 }, ...
$size将返回每个文档的projects
数组的长度,并$project更改文档的格式以包含totalProjects
作为{{1}的大小数组。
答案 1 :(得分:0)
您需要MongoDB的Aggregation Framework
:
db.users.aggregate({$unwind: '$projects'}).count()
这将展开集合中每个文档中的projects
数组字段,这将是projects
子文档的总数。
答案 2 :(得分:0)
您的设计中似乎可能有多个用户名文档,例如
{ username: "buzz", projects: [ list of 2 things ] }
{ username: "dan". projects: [ list of 3 things ] }
{ username: "buzz", projects: [ list of 4 things ] }
要获得每个username
项目的“赠款总额”,请尝试以下方法:
c = db.foo.aggregate([
{$project: {
"username": 1,
"n": {$size: "$projects"}
}
}
,
{$group: {
"_id": "$username",
"alln": {$sum: "$n"}
}
}
]);
产生
{ "_id" : "buzz", "alln" : 6 }
{ "_id" : "dan", "alln" : 3 }
答案 3 :(得分:0)
使用VirtualType()使用mongoose计数子文档的更好方法 让我们通过一个使用Blogpost和Comment模式设计的简单示例来了解这一点
const Blogpost = new Schema({
title: { type: String, required: true },
body: { type: String, required: true },
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },
commentId: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
lastModifiedAt: { type: Date, default: Date.now },
createdAt: { type: Date, default: Date.now },
})
const Comment = new Schema({
postId: { type: Schema.Types.ObjectId, ref: 'Post', required: true },
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },
text: { type: String, required: true },
lastModified: { type: Date, default: Date.now },
createdAt: { type: Date, default: Date.now }
})
现在,如果我们必须获取每篇博客文章的totalComments,那么我们必须在Blogpost架构设计中创建一个VirtualType
Blogpost.virtual('totalComments', {
ref: 'Comment', // model to use for matching
localField: '_id', // from `localField` i.e., Blogpost
foreignField: 'postId', // is equal to `foreignField` of Comment schema
count: true //only get the number of docs
});
Blogpost.set('toObject', { virtuals: true });
Blogpost.set('toJSON', { virtuals: true });
由于我们在Comment模式中具有postId,该id包含与该特定Blogpost关联的Blogpost._id,因此只有我们能够匹配并获取每个Blogpost的totalComments
现在使用人口,我们可以获得每个Blogpost的totalComments
let blogpost = await Blogpost.model
.find({})
.populate({ path: 'totalComments', count: true })