我目前有这个架构
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"来搜索模式。然后只从#34;传感器","执行器"中选择最后一个对象(按日期)。和"状态"阵列,但我无法弄清楚如何做到这一点。
通过这个查询,我可以部分实现我想要获得的东西,但它只给我一个数组,所以我必须三次查询数据库,我会避免这样做
db.getCollection('data').aggregate([
{ $match : { hid : "testhid" } },
{$project : {"sensors" : 1}},
{$unwind : "$sensors"},
{$sort : {"sensors.date" : -1}},
{$limit : 1}
])
提前感谢您提供任何帮助
答案 0 :(得分:1)
这里最好的建议是" store"首先排序的数组。有可能他们可能已经在考虑任何$push
操作(或者即使您使用.push()
)实际上只是"追加"到数组,以便最新项目是"最后"反正。
所以除非你真的"改变"创建后的"date"
属性,然后是"最新日期" 总是" last"项目无论如何。在这种情况下,仅$slice
条目:
Data.find({ "hid": "testhid" }).select({
"sensors": { "$slice": -1 },
"actuators": { "$slice": -1 },
"status": { "$slice": -1 }
}).exec(function(err,data) {
]);
"如果",某些原因你实际上设法以不同的方式存储或更改了"date"
属性,以便最新的不再是" last",那么将所有未来更新与$sort
的$push
修饰符一起使用可能是一个好主意。这可以确保"对数组的添加始终如一。您甚至可以在一个简单的语句中修改整个集合:
Date.update(
{},
{
"$push": {
"sensors": { "$each": [], "$sort": { "date": 1 } },
"actuators": { "$each": [], "$sort": { "date": 1 } },
"status": { "$each": [], "$sort": { "date": 1 } }
}
},
{ "multi": true },
function(err,num) {
}
)
在那一个声明中,集合中的每个文档都将所提到的每个数组重新排序到"最新日期"是"最后"每个数组的条目。这意味着$slice
的上述用法非常好。
现在"如果",绝对没有一个是可能的,你实际上有一些理由为什么数组条目不是通常以"date"
顺序存储,那么(并且只有真的那么你应该使用.aggregate()
来得到结果:
Data.aggregate(
[
{ "$match": { "hid": "testhid" } },
{ "$unwind": "$sensors" },
{ "$sort": { "_id": 1, "sensors.date": -1 } },
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}},
{ "$unwind": "$actuators" },
{ "$sort": { "_id": 1, "actuators.date": -1 } },
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}},
{ "$unwind": "$status" },
{ "$sort": { "_id": 1, "status.date": -1 } },
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}}
],
function(err,data) {
}
)
现实情况是,MongoDB无法进行内联排序"从任何查询或聚合管道语句返回的数组内容。您只能通过使用$unwind
然后使用$sort
处理,最后使用$group
处理$first
来有效地从排序数组中获取单个项目。
你需要这样做" per"数组,因为$unwind
的进程正在为每个数组项创建单独的文档。你"可能"一劳永逸地做到这一点:
Data.aggregate(
[
{ "$match": { "hid": "testhid" } },
{ "$unwind": "$sensors" },
{ "$unwind": "$actuators" },
{ "$unwind": "$status" }
{ "$sort": {
"_id": 1,
"sensors.date": -1,
"actuators.date": -1,
"actuators.status": -1
}},
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}}
],
function(err,data) {
}
)
但考虑到所有事情,对其他过程的改善并不是那么多。
这里的真实课程应该是"保持数组排序" 然后对$slice
执行操作最后一项是一个非常简单的过程。