我如何将在 $match 阶段内传递给 $in 运算符的每个 ID 限制为仅 4 个元素
Posted
技术标签:
【中文标题】我如何将在 $match 阶段内传递给 $in 运算符的每个 ID 限制为仅 4 个元素【英文标题】:How can i limit each ID i pass to $in operator inside the $match stage to only 4 elements 【发布时间】:2021-12-11 02:09:50 【问题描述】:我有一个这样的聚合:
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
字段之外的所有字段。
另外:我觉得我的方法不正确,我真正想要的是能够一次查询所有设施 ID,但仅限于为每个设施创建的 4 个最新文件,虽然我使用聚合会帮助我实现这一目标,但我开始认为这不是它的完成方式。
【问题讨论】:
使用$match
stage过滤后,可以在“facility”上进行分组,使用$push
进行文档堆积。然后,您可以限制在累积的数据范围内
【参考方案1】:
从问题来看,架构尚不清楚。所以我有两个基于两个模式的答案。请使用适合您的方法
#1
db.collection.aggregate([
$match:
facilityId:
$in: [
1,
2
]
,
$group:
_id: "$facilityId",
files:
$push: "$file"
,
$project:
files:
$slice: [
"$files",
0,
4
],
])
Test Here
#2
db.collection.aggregate([
$match:
facilityId:
$in: [
1,
2
]
,
$project:
facilityId: 1,
file:
$slice: [
"$file",
4
]
])
Test Here
【讨论】:
我已经编辑了我的问题并添加了架构和一些说明,我现在正在测试你的提议。 感谢您,我成功了,更改管道以返回我感兴趣的所有字段的 4 个元素的数组,并与 $facilityId 分组,我试图接受您的答案作为最终解决方案。以上是关于我如何将在 $match 阶段内传递给 $in 运算符的每个 ID 限制为仅 4 个元素的主要内容,如果未能解决你的问题,请参考以下文章
如何将在我的 Javascript 中创建的字符串数组传递给 C# 代码隐藏文件?