我目前有这个架构
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个元素。
答案 0 :(得分:1)
这可以通过聚合框架实现。 查询如下所示:
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个元素
答案 1 :(得分:1)
实际上,当“一个”执行时,不要使用多个管道阶段。您包含的每个管道阶段都有效地为处理添加“时间”,因为它是另一个通过数据的过程。
那么在“单一”阶段逻辑上有效,应该保持在“单一”阶段:
Data.aggregate([
{ "$match": { "hid": hid } },
{ "$project": {
"sensors": {
"$slice": [
{ "$filter": {
"input": "$sensors",
"as": "sensor",
"cond": { "$eq": [ "$$sensor.nid", nid ] }
}},
-10
]
},
"actuators": {
"$slice": [
{ "$filter": {
"input": "$actuators",
"as": "actuator",
"cond": { "$eq": [ "$$actuator.nid", nid ] }
}},
-10
]
},
"status": {
"$slice": [
{ "$filter": {
"input": "$status",
"as": "status",
"cond": { "$eq": [ "$$status.nid", nid ] }
}},
-10
]
},
"updated": 1,
"created": 1
}}
])
此外,除非明确“排除”,否则不必在"_id": 1
中包含"_id"
,因为{ "$sum": { "$sum": "$array" } }
始终。
主要的情况是尽量不创造不必要的阶段,因为它对性能不利。这方面的好指标是:
$project
后跟$project
,通常意味着您可以在一个阶段执行此操作。$project
后跟$group
可能会被“优化器”压缩,但你“应该”养成将这两者结合起来的习惯。$project
后跟$match
,表示您可能应该在一个阶段中使用$redact
。由于您可能会$project
根据计算生成字段,因此会在$match
中考虑这些字段。最后:
$unwind
之前$match
,$filter
之前$project
中的$unwind
真的应该是$unwind
。因为它实际上在文档中“过滤”的速度要快得多,并且由于来自已过滤内容的输出较少,因此还节省了处理$map
的成本。但还有一个:
所有“数组”操作,例如$filter
,$slice
,$sum
甚至“集合运算符”都应始终与每个“内联”使用另外,在那些操纵相同阵列内容的情况下。现在甚至适用于使用$max
或$group
进行包装,因为它们可以直接在数组本身上工作,并且通常看起来很奇怪但有效:
using (var db = new FORMS())
{
//Get Chapters from selected form
var query = from b in db.CHAPTERS
select b;
//Create treeview hierarchy
foreach (var rootItem in query)
{
TreeNode myNode = new TreeNode(rootItem.titulo, rootItem.id.ToString());
var childQuery = from b in db.SECTIONS
where b.idChapter = rootItem.id
select b;
//Add childs
foreach (var childItem in childQuery)
{
TreeNode myChildNode = new TreeNode(childItem.titulo, childItem.id.ToString());
myNode.ChildNodes.Add(myChildNode);
}
ChapterTreeView.Nodes.Add(myNode);
}
}
在{{3}}阶段内的结构。