我有一个这样的聚合:
const files = await File.aggregate([
{
$match: { facilityId: { $in: facilities } }
},
{
$sort: { createdAt: 1 }
},
{
$project: {
file: 0,
}
}
])
我想拥有每一个"设施"。只返回4个文件,我曾经做过类似facilities.map(id => query(id))
的事情,但我想在生产环境中加快速度。
使用$limit将限制整个查询,这不是我想要的,我尝试在投影阶段使用$slice,但得到了一个错误:
MongoError: Bad projection specification, cannot include fields or add computed fields during an exclusion projection
如何在单个查询中实现?
集合的模式为:
const FileStorageSchema = new Schema({
name: { type: String, required: true },
userId: { type: String },
facilityId: { type: String },
patientId: { type: String },
type: { type: String },
accessed: { type: Boolean, default: false, required: true },
file: {
type: String, //
required: true,
set: AES.encrypt,
get: AES.decrypt
},
sent: { type: Boolean, default: false, required: true },
},
{
timestamps: true,
toObject: { getters: true },
toJSON: { getters: true }
})
我想返回所有字段,除了包含base64编码的加密blob的file
字段。
也:我有一种感觉,我的方法是不正确的,我真正想要得到的是能够查询所有的facilityId,但仅限于为每个设施创建的4个最新文件,我虽然使用聚合将帮助我实现这一目标,但我开始认为它不是如何完成的。
从问题来看模式不清楚。所以基于两种图式,我有两个答案。请使用适合你的
# 1
db.collection.aggregate([
{
$match: {
facilityId: {
$in: [
1,
2
]
}
}
},
{
$group: {
_id: "$facilityId",
files: {
$push: "$file"
}
}
},
{
$project: {
files: {
$slice: [
"$files",
0,
4
],
}
}
}
])
测试在这里
# 2
db.collection.aggregate([
{
$match: {
facilityId: {
$in: [
1,
2
]
}
}
},
{
$project: {
facilityId: 1,
file: {
$slice: [
"$file",
4
]
}
}
}
])
测试在这里