我通過將事務保存到資料庫串列中來更新事務串列,我不想在串列中有重復的條目,所以我使用$addtoset
這是因為請求可以被多次觸發,我們希望確保任何更改對資料庫都是冪等的。現在唯一的問題是我們只想存盤最新的20 筆交易
這可以用 a 來完成,$push $sort $slice但我需要確保沒有重復的條目。早在 2015 年就有一個向 mongo 提出的功能請求,要求將其添加到$addtoset功能中,但他們拒絕了,因為“集合”沒有按順序排列……
這就是 $sort 功能
我以為我可以簡單地將一個空的推送更新附加到更新物件,但據我了解,每個更新都可能是執行緒化的,如果推送/切片在$addtoset
現在,這些值是具有以下公式的聚合字串,
timestamp:value但我可以輕松地將結構更改為物件
{ts:timestamp, value:value}
更新:當前代碼,不確定它是否會按預期作業,因為每個操作可能是獨立的
await historyDB
.updateOne(
{ trxnId: txid },
{
$addToSet: {
history: {
ts: time,
bid: bid.value,
txid: trxn.txid,
}
},
$push: {
history: {
$each: [{ts:-1}],
$sort: { ts: 1 },
$slice: -10,
},
},
},
{ upsert: true },
).exec();
uj5u.com熱心網友回復:
您的查詢不起作用,因為您嘗試history多次更新,這在簡單更新檔案中是不允許的,并且會引發錯誤Updating the path 'history' would create a conflict at 'history'。
但是,您隨后可以使用聚合管道history多次更新欄位。
await historyDB.updateOne(
{ trxnId: txid},
[{
$set: {
history: {
$let: {
vars: {
historyObj: {
ts: time,
bid: bid.value,
txid: trxn.txid,
},
historySafe: { $ifNull: ["$history", []] }
},
in: {
$cond: {
if: { $in: ["$$historyObj", "$$historySafe"] },
then: "$history",
else: { $concatArrays: [ "$$historySafe", ["$$historyObj"] ] }
}
}
}
}
},
},
{
$set: {
history: {
$function: {
body: function(entries) {
entries.sort((a, b) => a.ts - b.ts);
return entries;
},
args: [{ $ifNull: ["$history", []] }],
lang: "js"
}
}
},
},
{
$set: {
history: {
$slice: [ "$history", -10 ]
}
}
}],
{ upsert: true },
).exec()
從 MongoDB 6.0 開始,提供排序的第二$set階段可以替換為$sortArray運算子(請參閱此處)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/459374.html
上一篇:填充所有物件陣列
