Javascript MongoDB匹配并切片多个子数组
我目前有这个模式Javascript MongoDB匹配并切片多个子数组,javascript,mongodb,mongoose,mongodb-query,aggregation-framework,Javascript,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,我目前有这个模式 var dataSchema = new Schema({ hid: { type: String }, sensors: [{ nid: { type: String }, sid: { type: String }, data: { param1: { type: String }, param2: { type: String }, data: { type: String } },
var dataSchema = new Schema({
hid: { type: String },
sensors: [{
nid: { type: String },
sid: { type: String },
data: {
param1: { type: String },
param2: { type: String },
data: { type: String }
},
date: { type: Date, default: Date.now }
}],
actuators: [{
nid: { type: String },
aid: { type: String },
control_id: { type: String },
data: {
param1: { type: String },
param2: { type: String },
data: { type: String }
},
date: { type: Date, default: Date.now }
}],
status: [{
nid: {type: String},
status_code: {type: String},
date: { type: Date, default: Date.now }
}],
updated: { type: Date, default: Date.now },
created: { type: Date }
});
我试图构建的查询应该通过“hid”搜索模式,然后只从“传感器”、“执行器”和“状态”数组中选择与我提供的
nid
匹配的对象,然后还将每个数组的结果限制为10个元素。这可以通过聚合框架实现。
查询如下所示:
Data.aggregate([
{ "$match": { "hid": hid } },
{ "$project": {
"_id": 1,
"sensors": {
"$filter": { "input": "$sensors", "as": "sensor", "cond": { "$eq": [ "$$sensor.nid", nid ] } }
},
"actuators": {
"$filter": { "input": "$actuators", "as": "actuator", "cond": { "$eq": [ "$$actuator.nid", nid ] } }
},
"status": {
"$filter": { "input": "$status", "as": "state", "cond": { "$eq": [ "$$state.nid", nid ] } }
},
"updated": 1,
"created": 1
}},
{ "$project": {
"_id": 1,
"sensors": {
"$slice": [ "$sensors", -10 ]
},
"actuators": {
"$slice": [ "$actuators", -10 ]
},
"status": {
"$slice": [ "$status", -10 ]
},
"updated": 1,
"created": 1
}}
]).exec(function(err,data) {
});
它使用
$match
查找模式,使用$filter
从数组中仅选取与所提供的nid
匹配的元素,然后使用$slice
从过滤数组中选取最后10个元素,实际上,当“一个”就可以了时,不要使用多个管道阶段。您所包含的每个管道阶段都有效地为处理添加了“时间”,因为这是数据的另一次传递
因此,逻辑上在“单一”阶段起作用的内容应停留在“单一”阶段:
此外,没有必要在包含中使用“\u id”:1
,因为“\u id”
总是包含,除非明确“排除”
主要的情况是尽量不要创建不必要的阶段,因为这对性能有害。这方面的良好指标是:
- 后跟,通常意味着您可以在一个阶段内完成此操作
- 后跟可能会被“优化器”压缩,但您“应该”养成将两者结合的习惯
- 后跟,应该表示您可能应该在单个阶段中使用。由于您可能会根据计算生成字段,因此在中会考虑这些字段
- 以前的一个,真的应该是一个在一个“以前”的。事实上,在文档中“过滤”的速度要快得多,而且由于已过滤内容的输出更少,因此还可以节省处理文档的成本
- 在操作相同数组内容的情况下,所有“数组”操作(例如,甚至“集合运算符”)都应始终相互“串联”使用。这一点现在甚至适用于使用或现在进行包装,因为它们可以直接在阵列本身上工作,并且通常使用外观奇特但有效的:
舞台中的结构{ "$sum": { "$sum": "$array" } }
{ "$sum": { "$sum": "$array" } }