共计 4790 个字符,预计需要花费 12 分钟才能阅读完成。
mongoexport 命令行用于数据的导出,默认导出的文件格式为 JSON 格式。当然也可以指定特定的文件格式。
语法
C:\mongo\bin mongoexport -help
options:
–help produce help message
-v [–verbose] be more verbose (include multiple times for more
verbosity e.g. -vvvvv)
-h [–host] arg mongo host to connect to (set name /s1,s2 for sets)
–port arg server port. Can also use –host hostname:port
–ipv6 enable IPv6 support (disabled by default)
-u [–username] arg username
-p [–password] arg password
–dbpath arg directly access mongod database files in the given
path, instead of connecting to a mongod server –
needs to lock the data directory, so cannot be used
if a mongod is currently accessing the same path
–directoryperdb if dbpath specified, each db is in a separate
directory
-d [–db] arg database to use
-c [–collection] arg collection to use (some commands)
-f [–fields] arg comma separated list of field names e.g. -f name,age
–fieldFile arg file with fields names – 1 per line
-q [–query] arg query filter, as a JSON string
–csv export to csv instead of json
-o [–out] arg output file; if not specified, stdout is used
–jsonArray output to a json array rather than one object per
Line
说明:
-h:数据库宿主机的 IP
-u:数据库用户名
-p:数据库密码
-d:数据库名字
-c:集合的名字
-f:导出的列名
-q:导出数据的过滤条件
–csv:导出格式为 csv
引言
今天在用 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 需要显示指定才可以。+
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对丸趣 TV 的支持。
向 AI 问一下细节
丸趣 TV 网 – 提供最优质的资源集合!