假設我有一個模型如下
import {model, Schema, Types} from 'mongoose'
import { IResource } from '../interfaces'
const ResourceSchema = new Schema<IResource>({
user : {type : Schema.Types.ObjectId, ref : 'users'},
type : {type: Schema.Types.ObjectId , ref : 'resource_datas'},
building : {type : Schema.Types.ObjectId , ref : 'buildings'},
lastUpdate : {type : Date , default : Date.now},
value : {type : Number, default : 500},
valuePerHours : {type : Number, default : 0}
})
const Resources = model<IResource>('resources' , ResourceSchema)
export default Resources
和樣本記錄:
[
{
user : User_ID,
type : Type_ID,
building : Building_ID,
lastUpdate : Date("2022-03-21T08:32:40.866 00:00"),
value : 500,
valuePerHours : 120
},
{
user : User_ID,
type : Type_ID,
building : Building_ID,
lastUpdate : Date("2022-03-21T08:22:40.866 00:00"),
value : 540,
valuePerHours : 150
},
{
user : User_ID,
type : Type_ID,
building : Building_ID,
lastUpdate : Date("2022-03-21T08:36:40.866 00:00"),
value : 1200,
valuePerHours : 180
},
]
How can I update field "value" as often as possible?
Currently, I do like bellow
while (true) {
const resources = await Resources.find({})
.limit(100)
.sort({lastUpdate : 1})
.populate('building')
const promiseSave = []
for (let index = 0; index < resources.length; index ) {
const resource = resources[index];
const now = Date.now()
const diffTime = (now - new Date(resource.lastUpdate).getTime()) / 1000
const percentDiffTimePerHour = diffTime / 3600000
const generate = resource.valuePerHours
const valueAfterDiff = generate * percentDiffTimePerHour
resource.value = valueAfterDiff
resource.lastUpdate = now
promiseSave.push(resource.save())
}
await Promise.all(promiseSave)
}
//update value follow lastUpdate and valuePerHours
Every round for find 100 records and save them, It took about 200ms if I have 1mil record, It will take 2000seconds to update all records. I can update it once per hour or per day. But better it should nearly "real-time". Any better way to do that? Thanks for reading.
uj5u.com熱心網友回復:
您不需要任何回圈或花哨的邏輯。您可以運行一個簡單的更新聚合管道:
db.Resources.updateMany({}, [
{
$set: {
lastUpdate: "$$NOW",
value: {
$sum: ["$value", {
$multiply: [{
$divide: [
{ $dateDiff: { startDate: "$lastUpdate", endDate: "$$NOW", unit: "second" } },
60 * 60 * 1000
]
}, "$valuePerHours"]
}]
}
}
}
])
或者更短一點:
db.Resources.updateMany({}, [
{
$set: {
lastUpdate: "$$NOW",
value: {
$sum: ["$value", {
$multiply: [
{ $dateDiff: { startDate: "$lastUpdate", endDate: "$$NOW", unit: "second" } },
"$valuePerHours",
1 / 60 / 60 / 1000
]
}]
}
}
}
])
這更新value了秒的解析度。如果您需要毫秒的解析度,請使用
db.Resources.updateMany({}, [
{
$set: {
lastUpdate: "$$NOW",
value: {
$sum: ["$value", {
$multiply: [{
$divide: [
{ $dateDiff: { startDate: "$lastUpdate", endDate: "$$NOW", unit: "millisecond" } },
60 * 60 * 1000 * 1000
]
}, "$valuePerHours"]
}]
}
}
}
])
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/447313.html
