我有一個MongoDB的集合,命名爲玩家MongoDB的數據模型和更新策略
_id, name, stats[ { stName, stValue, stCountC } ]
我會爲每個玩家每天可以更新各種統計數據,但是當發現一個新的值將只更新統計值(即,new.stCount > existing.stCountC
)。我的一般想法是將每個唯一stName
的統計數組限制爲2個對象 - 一個用於Current值,另一個用於Previous值。如果上面的查詢返回文檔
db.players.findOne({ name: "JSmith",
stats: { $elemMatch: { stName: "Avg", stCountC: 5 } } })
,然後我更新內容如下 - - 舉例因此,讓我們說我找到的6計數一個新的統計,我的查詢和更新過程將開始與
1)獲取jsmith的stValue
其中stName = "Avg"
和stCountP = 4
-
db.players.findOne({ name: "JSmith", stats: { stName: "Avg", stCountP: 4 } },
{ stats.$.stValue })
2)插入此值到我的收藏StatsHistory
,它擁有所有的歷史值,每個球員單個統計類型 -
db.statshistory.update({ Name: "JSmith", StatName: "Avg" },
{ $addToSet : { oldValues : { stValue: <val>, stCount: 4 } } })
3)更新我的收藏Players
-
db.players.update({ Name: JSmith },
{ $push: { stats: { stName: "Avg", stValue: "98", stCountC: 6 } }
$pull: { stats: { stName: "Avg", stCountP: 4 } } })
db.players.update({ name: "JSmith", stats.stName: "Avg", stats.stCountC: 5 },
{ $rename: { "stats.stCountC": "stats.stCountP" } })
我會從玩家收集來呈現當前統計值的數據網格(即每個玩家一排,每名統計一列)。我還會看到顯示統計值趨勢的視圖,並假設我將使用MongoDB的聚合函數從StatsHistory集合中返回這些值。
問題:上面的數據模型和查找/更新過程是否合乎邏輯?
我很明顯是MongoDB的新手,所以對任何語法錯誤表示歉意,或者如果上述看起來完全不符合我的需求。任何反饋非常感謝!
解決: 感謝idbentley爲下面的建議。它幫助我使用async.js設計了以下數據庫更新過程。請注意,數據模型略有變化 - Players
集合現在僅保存最新的統計值,每個嘗試更新通過更新主記錄上的LastScan
日期戳,並且每個統計更新提供日期戳LastUpdate
。統計數仍用於檢查返回的統計數據是否更新。這個程序還可以確保任何新玩家/統計數據都被插入到收藏中。
async.series([
function(cb){ db.statshistory.update({ Name: <name>, StatName: <statname> },
{ $set : { LastScan: new Date() }},
{ upsert: true },
function() { cb(); });
}
,function(cb){ db.statshistory.update({ Name: <name>, StatName: <statname>, OldValues: { $not : { $elemMatch : { StCount: <statcount> }}}},
{ $push : { OldValues: { LastUpdate: new Date(), StCount: <statcount>, StValue: <statvalue> }}},
function() { cb(); });
}
,function(cb){ db.players.update({ Name: <name> },
{ $set : { LastScan: new Date() }},
{ upsert: true },
function() { cb(); });
}
,function(cb){ db.players.update({ Name: <name> },
{ $pull : { Stats: { StName: <statname>, StCount: { $ne: <statcount> }}}},
function() { cb(); });
}
,function(cb){ db.players.update({ Name: <name>, Stats: { $not : { $elemMatch : { StName: <statname>, StCount: <statcount> }}}},
{ $push : { Stats: { LastUpdate: new Date(), StCount: <statcount>, StValue: <statvalue> }}},
function() { cb(); });
}]
,function() { console.log('update complete'); }
)