1. 程式人生 > >MongoDB 執行mongoexport時異常及分析

MongoDB 執行mongoexport時異常及分析

-type pytho -c 語句 推斷 轉換 The 3.4 not

今天在用mongoexport導出滿足一定條件下的數據時,遇到了一個報錯,現紀錄下來,並且針對此錯誤對MongoDB 的?數字類型?做了進一步的學習。

背景及報錯信息?
今天接到一個業務需求,需要從MongoDB 數據庫 order集合中導出符合以下條件的數據:

db.qqwj_order.find({"Source":NumberInt("21"),"Batch":"支付中的訂單提醒:2018/9/5","MsgContent":/還未完成在線付款/})

通過MongoDB 客戶端工具 【NoSQLBooster for MongoDB】查詢檢查,語句執行正常,顯示相應記錄數為 15265。

導出數據使用mongoexport命令,執行命令如下:

/data/mongodb/mongobin344/bin/mongoexport?-h 172.X.X.XXX --port 端口 --db 數據庫 -u 賬號 -p ‘密碼‘ --authenticationDatabase 認證數據庫 --type=csv -c qqwj_order -f MsgContent,REC_CreateTime??-q ‘{ "Source":NumberInt("21"),"Batch":"支付中的訂單提醒:2018/9/5","MsgContent":/還未完成在線付款/}‘?-o?/data/mongodb_back/sms.csv?

但是執行報錯:

XXX is not valid JSON: json: cannot unmarshal string into Go value of type json.NumberInt

錯誤截圖如下:

錯誤推斷及測試
因為報錯信息中NumberInt 關鍵字,此時去看我們的查詢條件正好也有此關鍵字,所以推測 是不是這個問題。

結果將導出命令中的 NumberInt("21") 直接替換為 21 ,再次執行。

執行命令為 :

/data/mongodb/mongobin344/bin/mongoexport?-h 172.X.X.XXX --port 端口 --db 數據庫 -u 賬號 -p ‘密碼‘ --authenticationDatabase 認證數據庫 --type=csv -c qqwj_order -f MsgContent,REC_CreateTime?-q ‘{"Source":21,"Batch":"支付中的訂單提醒:2018/9/5","MsgContent":/還未完成在線付款/}‘ -o?/data/mongodb_back/sms.csv

執行結果為

結果表明修改後,數據成功導出。

錯誤解析與原理探究
為什麽通過查詢器查看,數據就是????"Source" : NumberInt("21"),但是在shell 中的執行導出命令寫成"Source" : NumberInt("21") 就會報錯。而一定要轉換為"Source":21

查詢器查詢出的Source字段顯示:

明明就是?"Source" : NumberInt("21"),為什麽復制到shell,執行報錯???

回頭看,找原理。我們知道目前MongoDB 支持4中數據類型。

double
32-bit integer
64-bit integer
Decimal (New in version 3.4.)
在MongoDB客戶端可以執行查詢,但是在shell中無法執行導出,那麽會不會和這兩種工具有關?會不會和插入的NumberInt(數字) 還是NumberInt(‘數字‘)有關?

下面對假設進行驗證測試。

通過 NoSQLBooster for MongoDB 方式 插入測試數據

通過 shell方式插入測試數據

通過$type 去查看插入的數據類型

1》執行db.numbers.find({n:{$type:1}})?// Type 為 Double;查詢Type 為 Double的數據

以上查詢結果顯示,不管是通過客戶端還是shell,當數字不指明數據類型時,插入的數字數據默認都是Double。

?2》執行命令 db.numbers.find({n:{$type:16}})?// Type 為 32-bit integer ;查詢Type 為 32-bit integer的數據

以上查詢表名,不管通過客戶端還是shell,指定的NumberInt(5) 還是NumberInt(‘5‘) 後臺都轉成統一32-bit integer 類型存儲了。

?3》執行命令 db.numbers.find({n:{$type:18}})?// Type 為 64-bit integer 查詢Type 為 64-bit integer的數據

以上查詢表名,不管通過客戶端還是shell,指定的NumberLong(5) 還是NumberLong(‘5‘) 後臺都轉成統一64-bit integer 類型存儲了。

以上的測試說明,當我們在存儲數字數據時會自動轉儲(不管什麽客戶端工具,是shell還是 【NoSQLBooster for MongoDB】,不管 NumberLong(5) 還是NumberLong(‘5‘);NumberInt(5) 還是NumberInt(‘5‘))。

有點糊塗了吧? 如此這樣,那為什麽 在查詢是報錯呢?

回頭再看錯誤提示:XXX is not valid JSON: json: cannot unmarshal?string?into Go value of type json.NumberInt。

其意思是shell 認為我們把一個字符類型的數據傳給了 json.NumberInt。

那我如果將導出命令中的 NumberInt("21") 將 換成 NumberInt(21)

執行命令為 :

/data/mongodb/mongobin344/bin/mongoexport?-h 172.X.X.XXX --port 端口 --db 數據庫 -u 賬號 -p ‘密碼‘ --authenticationDatabase 認證數據庫 --type=csv -c qqwj_order -f MsgContent,REC_CreateTime?-q ‘{"Source": NumberInt(21),"Batch":"支付中的訂單提醒:2018/9/5","MsgContent":/還未完成在線付款/}‘ -o?/data/mongodb_back/sms.csv?

執行也成功。

結論
說了很多總結下:

執行失敗的導出命令是:

/data/mongodb/mongobin344/bin/mongoexport?-h 172.X.X.XXX --port 端口 --db 數據庫 -u 賬號 -p ‘密碼‘ --authenticationDatabase 認證數據庫 --type=csv -c qqwj_order -f MsgContent,REC_CreateTime?-q ‘{ "Source":NumberInt("21"),"Batch":"支付中的訂單提醒:2018/9/5","MsgContent":/還未完成在線付款/}‘ -o?/data/mongodb_back/sms.csv?

執行成功的導出命令是:

/data/mongodb/mongobin344/bin/mongoexport?-h 172.X.X.XXX --port 端口 --db 數據庫 -u 賬號 -p ‘密碼‘ --authenticationDatabase 認證數據庫 --type=csv -c qqwj_order -f MsgContent,REC_CreateTime?-q ‘{"Source":21,"Batch":"支付中的訂單提醒:2018/9/5","MsgContent":/還未完成在線付款/}‘ -o?/data/mongodb_back/sms.csv和?

/data/mongodb/mongobin344/bin/mongoexport?-h 172.X.X.XXX --port 端口 --db 數據庫 -u 賬號 -p ‘密碼‘ --authenticationDatabase 認證數據庫 --type=csv -c qqwj_order -f MsgContent,REC_CreateTime?-q ‘{"Source":?NumberInt(21),"Batch":"支付中的訂單提醒:2018/9/5","MsgContent":/還未完成在線付款/}‘ -o?/data/mongodb_back/sms.csv?

三個導出命令不同的地方已用紅色字體標註。

P.S?1?:後來作者深究了一下,為什麽同樣的查詢,通樣的查詢結果,有的顯示?"n" : 5?; 有的顯示 "n" : NumberInt("5")。嘻嘻 》》》》版本不同而已。

舊版本(部分)的顯示

新版本(例如nosqlbooster4mongo-4.7.1)的顯示

P.S?2?:在存儲數字數據時,到底會存儲為何種數據類型,其實和語言的的驅動有關。例如在Ruby 和 Python 語言裏在序列化整數時,驅動會自動確定是否編碼為32-bit integer 還是?64-bit integer;shell 需要顯示指定才可以。

MongoDB 執行mongoexport時異常及分析