標籤:
最近在寫一個lua的MongoDB模組。MongoDB版本3.2,lua則是5.3.1。底層以C++來寫,再把函數暴露給lua調用。但是在lua中列印結果時,發現了些奇怪的現象。首先,資料庫中的內容:
> db.item.find(){ "_id" : 2001, "amount" : 999 }{ "_id" : 2002, "amount" : 78, "name" : "kfsjadlfasfkljeihfdsfkasfjslkfjei" }
當然,這是我隨手寫來測試的,沒什麼意義。然而在lua中列印是這樣的:
table: 0xff0ae0{ "1" = table: 0xfe4800 { "name" = "kfsjadlfasfkljeihfdsfkasfjslkfjei" "_id" = 2002.0 "amount" = 78.0 } "0" = table: 0xfe4610 { "amount" = 999.0 "_id" = 2001.0 }}
資料是正確的,問題在於:像2001這些整形數字為什麼都有了小數點。稍微跟蹤一下代碼,就可以發現:從MongoDB find出來的資料,已經是double,因此在返回lua層時使用了lua_pushnumber而不是lua_pushinteger,才導致lua認為該數字為number而不是integer。小數點就是這麼來的。
然而MongoDB的資料是基於bson的,而bson是有int類型的。那麼,說明資料在輸入MongoDB時類型就已經是double了。而資料是我在mongo shell中輸入的,問題就得從mongo shell查起。
在官網https://docs.mongodb.org/v3.0/core/shell-types/中提到,mongo shell是有類型的。但我們在輸入時,一般是這樣輸入的:
db.item.insert( {_id:2002,amount:78} )
沒有指定任何類型,並且,使用的是json格式。問題就來了:json格式只有number類型,並沒有細分int、double之類的數字,那麼為了保險起見,顯然mongo shell全部把它存為了double類型。官方顯然早就注意到了這個問題,允許在shell中輸入資料時指定類型,比如:
db.item.insert( {_id:NumberInt(2009),amount:78,name:"kfsjadlfasfkljeihfdsfkasfjslkfjei"} )
使用NumberInt之類的函數來指定類型。指定之後,在lua中現次查詢,結果為:
table: 0xff0ae0{ "2" = table: 0xfe5cd0 { "name" = "kfsjadlfasfkljeihfdsfkasfjslkfjei" "_id" = 2009 "amount" = 78.0 } "1" = table: 0xfe4800 { "name" = "kfsjadlfasfkljeihfdsfkasfjslkfjei" "_id" = 2002.0 "amount" = 78.0 } "0" = table: 0xfe4610 { "amount" = 999.0 "_id" = 2001.0 }}
探索資料2009是顯示正常的。以後程式運行時,資料是從程式輸入的,這也就不成問題。
MongoDB的資料類型