需求描述:
需要用MongoClient模塊 ,TypeScript語言 來做一個注冊表功能。
要保證玩家的userid 是自增的、唯一的。
注意:這不是關於MongoClient讀寫數據庫的基礎教程。(這方面基礎知識,請百度 菜鳥教程)
這是一個真實案例。是關於如何在MongoDB里面,實現某個字段的自增長。。。例如玩家注冊的時候,userid要保證唯一。
當前版本號:MongoDB shell version v4.2.5
官方對於API的解釋:
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findOneAndUpdate
對於 $inc 的解釋:
https://docs.mongodb.com/manual/reference/operator/update/inc/#up._S_inc
https://mongodb.github.io/node-mongodb-native/api-articles/nodekoarticle1.html
/**1.連接數據庫服務器*/ MongoClient.connect(url, function (err, dbClient) { //assert.equal(err, null); if (err) { MyUtil.outputErrorInfo("MongoDBManager", "userRegister", "register error"); console.error(err); objReturn.code = NetMessageID.ERROR_CODE.REGISTER_FAILED; objReturn.des = "注冊失敗,數據庫有問題"; resolve(objReturn); dbClient.close(); return; } /**2.連接某個具體的數據庫*/ const UserDB = dbClient.db(dbname); /**3.連接數據庫的某個表*/ const registerCollection = UserDB.collection(table_register);
registerCollection.findOneAndUpdate( { increase: 1 }, { $inc: { userid: 1 }, $set: { des: "This line record total num" } }, { "upsert": true, "returnOriginal": false }, (err, res) => { if (err) { console.error(err); MyUtil.outputErrorInfo("MongoDBManager", "userRegister", "insert error"); console.error(err); objReturn.code = NetMessageID.ERROR_CODE.REGISTER_FAILED; objReturn.des = "注冊失敗,保存數據庫失敗,未知錯誤1"; objReturn.userid = 0; resolve(objReturn); dbClient.close(); return; } /**取出了遞增的id值,把玩家userid字段賦值*/ oneUser.userid = MongoDBManager.g_BaseUserID + res.value.userid; /**插入我們的新數據 */ registerCollection.insertOne(oneUser, (err, res) => { if (err) { MyUtil.outputErrorInfo("MongoDBManager", "userRegister", "insert error"); console.error(err); objReturn.code = NetMessageID.ERROR_CODE.REGISTER_FAILED; objReturn.des = "注冊失敗,保存數據庫失敗,未知錯誤"; objReturn.userid = 0; resolve(objReturn); dbClient.close(); return; } }); /**如果一切正常,會走到這里.把userid值放入返回值,傳遞出去 */ objReturn.userid = oneUser.userid objReturn.code = NetMessageID.ERROR_CODE.IS_OK; objReturn.des = "注冊成功"; MyUtil.outputErrorInfo("MongoDBManager.ts", "userRegister", `新玩家[${regist.username}]注冊成功,userid:${objReturn.userid}`); resolve(objReturn); dbClient.close();
數據庫效果圖:
我們這里調用了2次 Mongo的函數。
1.調用findOneAndUpdate 函數。這個是原子操作,它始終只會讀寫第一條數據。每次主要目的就是記錄自增值。
2.調用insertOne函數, 插入一條數據。。。我們是在 findOneAndUpdate 的回調中調用的,意思就是獲取到自增的值之后,我們才知道真正的userid是都少,才正式把玩家的注冊信息保存到數據庫。
這些字段是什么意思,請參考前面貼出的連接的文章。
{ increase: 1 },{ $inc: { userid: 1 }, $set: { des: "This line record total num" } },{ "upsert": true, "returnOriginal": false }
最后,傳送門,這是我的項目代碼地址:https://github.com/liangzai90/websocket-server-and-client