只需将尺寸相加:
在 MongoDB 3.4 或更高版本中使用$concatArrays
Model.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": {
"$concatArrays": [
{ "$ifNull": [ "$organisers", [] ] },
{ "$ifNull": [ "$volunteers", [] ] },
{ "$ifNull"; [ "$participants", [] ] },
{ "$ifNull": [ "$mentors", [] ] }
]
} },
500
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": { "_id": 1 } }
],function(err,results) {
})
或者在没有该运算符的早期版本中
Model.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$add": [
{ "$size": { "$ifNull": [ "$organisers", [] ] } },
{ "$size": { "$ifNull": [ "$volunteers", [] ] } },
{ "$size": { "$ifNull": [ "$participants", [] ] } },
{ "$size": { "$ifNull": [ "$mentors", [] ] } }
]},
500
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": { "_id": 1 } }
],function(err,results) {
})
在任何一种方法中,您都使用$redact 作为集合中文档的逻辑过滤器。作为本地操作员,这是您处理这种情况的最快方式。
在内部,它的唯一参数是$cond,这是一个“三元”操作( if/then/else )来评估和返回一个值。因此,当"if" 条件的结果导致true、"then" 时,操作是$$KEEP 文档,或者"else" 到$$PRUNE 结果中的文档。
基于版本的不同方法是:
至于只返回_id 字段,那么添加$project 阶段就很简单了,就像在常规查询投影中一样,您提供要返回的属性列表。在这种情况下,只有_id 字段。
您可以先使用$match 在基本查询中添加一些关于最小数组长度的假设,但这只是一个假设,而不是绝对事实。
作为记录,您可以使用 $where 子句运行完全相同的东西,但是由于此运算符使用 JavaScript 评估,而不是像聚合框架操作那样本机实现,因此它确实会对性能产生重大影响它运行得更慢:
Model.find({ "$where": function() {
return [
...this.organisers,
...this.volunteers,
...this.participants,
...this.mentors
].length > 500
}).select({ "_id": 1 }).exec(function(err,results) {
})
因此,与聚合管道结构的 DSL 形式相比,它可能“看起来很漂亮”,但性能损失并不值得。只有当您的 MongoDB 版本缺少 $redact 作为运算符时,您才应该这样做,这将在 MongoDB 2.6 之前。在这种情况下,您可能还应该出于其他原因更新 MongoDB。