gpt4 book ai didi

javascript - 从多个数组中返回最新的排序日期

转载 作者:可可西里 更新时间:2023-11-01 10:42:22 26 4
gpt4 key购买 nike

我目前有这个架构

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”搜索模式,然后只从“sensors”、“actuators”和“status”数组中选择最后一个对象(按日期),但我不能不知道该怎么做。

通过这个查询,我可以部分实现我想要得到的结果,但它一次只给我一个数组,所以我必须查询数据库三次,我会避免这样做

db.getCollection('data').aggregate([
{ $match : { hid : "testhid" } },
{$project : {"sensors" : 1}},
{$unwind : "$sensors"},
{$sort : {"sensors.date" : -1}},
{$limit : 1}
])

在此先感谢您的帮助

最佳答案

这里最好的建议是首先按排序“存储”数组。有可能他们可能已经在考虑任何 $push操作(或者即使您使用了 .push() )实际上只是“追加”到数组,以便最新的项目无论如何都是“最后的”。

因此,除非您在创建后实际“更改”“日期” 属性,否则“最新日期”始终无论如何都是“最后一个”项目。在这种情况下,只需 $slice条目:

Data.find({ "hid": "testhid" }).select({
"sensors": { "$slice": -1 },
"actuators": { "$slice": -1 },
"status": { "$slice": -1 }
}).exec(function(err,data) {

]);

“如果”,出于某种原因,您实际上确实设法以不同的方式存储或更改了 “date” 属性,因此它们最新的不再是“最后的”,那么这可能是个好主意让所有 future 的更新使用 $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有效地从排序数组中获取单个项目。

这需要对“每个”数组执行此操作,因为 $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 进行操作,最后一项是非常简单的过程。

关于javascript - 从多个数组中返回最新的排序日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36700350/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com