我有一个Mongoose Schema定义如下:
const hackathonSchema = new mongoose.Schema({
hackathonId: {type: Number, required: true},
uuid: {type: String, required: true},
data: {type: Object, required: true},
isPublished: {type: Boolean, default: false},
organisers: [String],
volunteers: [String],
participants: [String],
mentors: [String]
});
export default mongoose.model('Hackathon', hackathonSchema);
我想要检索所有的Hackathons 长度:
( organisers + volunteers + participants +mentors ) >= 500
或该问题的任何价值。
我找到了SO的答案,而不是Mongoose How to select where sum of fields is greater than a value in MongoDB
答案 0 :(得分:1)
只需将尺寸加在一起:
的MongoDB 3.4或更高版本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
来自结果的文件。
基于版本的不同方法是:
$concatArrays
为了制作一个“大”数组并将其返回$size
至于仅仅返回_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。