MongoDB执行mongoexport时的异常及分析(数字类型的查询)

  • A+
所属分类:MongoDB

概述

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"大众: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 必要显示指定才可以。+

总结

以上便是这篇文章的全体内容了,愿望本文的内容对年夜家的进修或者事情具有必定的参考进修代价,假如有疑问年夜家可以留言交流,谢谢年夜家对剧本之家的支撑。

您可能感兴致的文章:

应用Mongoose让JSON数据直接插入或更新到MongoDBJSON 的正确用法探究:Pyhong、MongoDB、JavaScript与Ajaxpython读取json文件并将数据插入到mongodb的办法MongoDB批量将光阴戳转为通用日期格局示例代码Python实现批量读取图片并存入mongodb数据库的办法示例Mongodb批量删除gridfs文件实例MongoDB单表数据的导出和规复实例讲授MongoDB备份、还原、导出、导入、克隆操作示例深刻阐发Mongodb数据的导入导出MongoDB导出查询成果到文件例子mongodb 数据库操作--备份 还原 导出 导入MongoDB使用mongoexport和mongoimport敕令,批量导出和导入JSON数据到统一张表的实例

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: