我有一个带有子文档的文档(未引用 )。我想将汇总应用于子文档的字段。
架构
const MFileSchema = new Schema({
path: String,
malwareNames: [String],
title: String,
severity: String // i want to aggregate bases on this field
});
const ScanSchema = new Schema({
agent: { type: Schema.Types.ObjectId, ref: "Agent" },
completedAt: Date,
startedAt: { type: Date, default: Date.now() },
mFiles: [MFileSchema] // array of malicious files schema
});
模型
let Scan = model("Scan", ScanSchema);
任务
Find the sum of severity in all scan documents of particular agents.
// agents is an array Agents (the schema is not important to show, consider the _id)
我正在使用的汇总查询
let c = await Scan.aggregate([
{ $match: { agent: agents } },
{ $project: { "mFiles.severity": true } },
{ $group: { _id: "$mFiles.severity", count: { $sum: 1 } } }
]);
console.log(c);
实际输出
[]
预期产量
// The value of count in this question is arbitrary
[
{ _id: "Critical", count: 30 },
{ _id: "Moderate", count: 33 },
{ _id: "Clean", count: 500 }
]
PS:如果您能向我推荐学习MongoDB聚合的最佳资源,我也将不胜感激
答案 0 :(得分:1)
您需要在$ match阶段使用$in查询运算符,并在$ group阶段之前添加$unwind阶段。
db.collection.aggregate([
{
$match: {
agent: {
$in: [
"5e2c98fc3d785252ce5b5693",
"5e2c98fc3d785252ce5b5694"
]
}
}
},
{
$project: {
"mFiles.severity": true
}
},
{
$unwind: "$mFiles"
},
{
$group: {
_id: "$mFiles.severity",
count: {
$sum: 1
}
}
}
])
样本数据:
[
{
"agent": "5e2c98fc3d785252ce5b5693",
"mFiles": [
{
"title": "t1",
"severity": "Critical"
},
{
"title": "t2",
"severity": "Critical"
},
{
"title": "t3",
"severity": "Moderate"
},
{
"title": "t4",
"severity": "Clean"
}
]
},
{
"agent": "5e2c98fc3d785252ce5b5694",
"mFiles": [
{
"title": "t5",
"severity": "Critical"
},
{
"title": "t6",
"severity": "Critical"
},
{
"title": "t7",
"severity": "Moderate"
}
]
}
]
输出:
[
{
"_id": "Moderate",
"count": 2
},
{
"_id": "Critical",
"count": 4
},
{
"_id": "Clean",
"count": 1
}
]
对于猫鼬整合:
//agents must be an array of objectIds like this
// [ObjectId("5e2c98fc3d785252ce5b5693"), ObjectId("5e2c98fc3d785252ce5b5694")]
//or ["5e2c98fc3d785252ce5b5693","5e2c98fc3d785252ce5b5694"]
const ObjectId = require("mongoose").Types.ObjectId;
let c = await Scan.aggregate([
{
$match: {
agent: {
$in: agents
}
}
},
{
$project: {
"mFiles.severity": true
}
},
{
$unwind: "$mFiles"
},
{
$group: {
_id: "$mFiles.severity",
count: {
$sum: 1
}
}
}
]);
学习mongodb聚合的最佳场所是official docs。