我有一個集合,它為每個 uID(這是主鍵)每 2 秒存盤一次資料。現在我想查詢每個 uID 的最后 30 個檔案,并根據它們的索引號將它們組合在一起。在這種情況下如何進行?如果我應用 $limit,這將只回傳所有 uID 的 30 個檔案。
db.getCollection("devices").aggregate(
[
{
"$match" : {
"uID" : {
"$in" : [
"20200308",
"20200306",
"12345678"
]
}
}
}
],
{
"allowDiskUse" : false
}
);
上述查詢將回傳所有檔案,如何將查詢限制為每個 uID 30 個檔案?此外,如果查詢成功,如何對不同檔案的所有陣列索引進行分組,以便我得到一個包含 30 個檔案組合在一起的欄位的值的總和。例子:
[
{
_id: 0, // index value of all array after grouping them.
sumOfValuesFoundInArrayIndex: 100,
},
{
_id: 1,
sumOfValuesFoundInArrayIndex: 600,
}
.
.
.
.
{
_id: 29,
sumOfValuesFoundInArrayIndex: 600,
}
]
JSON 示例:
[
{
"timeStamp": 1644962269,
"uID": "20200308",
"capacityLeft": 500
},
{
"timeStamp": 1644962272,
"uID": "20200308",
"capacityLeft": 499
},
{
"timeStamp": 1644962275,
"uID": "20200306",
"capacityLeft": 300
},
{
"timeStamp": 1644962277,
"uID": "20200308",
"capacityLeft": 499
},
{
"timeStamp": 1644962277,
"uID": "20200306",
"capacityLeft": 300
},
{
"timeStamp": 1644962279,
"uID": "12345678",
"capacityLeft": 753
},
{
"timeStamp": 1644962281,
"uID": "12345678",
"capacityLeft": 752
},
{
"timeStamp": 1644962283,
"uID": "12345678",
"capacityLeft": 751
}
]
現在根據 JSON,我需要為每個 uID 找到 30 個檔案并使用 timeStamp 對它們進行排序,這樣當我查詢所有提到的設備時,我會得到提到的 uID 的最后 30 個檔案,按它們的陣列索引對它們進行分組,然后求和剩余的所有容量。
uj5u.com熱心網友回復:
在我看來是這樣的:
db.collection.aggregate([
{
$match: {
uID: {
$in: [
"20200308",
"20200306"
]
}
}
},
{
$sort: {
uID: 1,
"timeStamp": -1
}
},
{
$group: {
_id: "$uID",
ts: {
$push: "$$ROOT"
}
}
},
{
$project: {
ts: {
$slice: [
"$ts",
30
]
}
}
},
{
$unwind: "$ts"
},
{
$group: {
_id: "$_id",
sumcapLast30: {
$sum: "$ts.capacityLeft"
}
}
}
])
解釋:
- 匹配所有需要的 uID
- 按 uID 排序,按 timeStamp 降序
- 按 uID 分組
- 拼接并僅保留 ts 陣列中的前 30 個元素。
- 展開 ts 陣列
- 對每個 uID 的前 30 個元素進行分組和求和
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/455114.html
