MongoDB 执行mongoexport时异常及分析(关于数字类型的查询)
今天在用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":,"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时异常及分析(关于数字类型的查询)的更多相关文章
- Angular js 双向绑定时字符串的转换成 数字类型的问题
问题: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <scrip ...
- 使用dynamic引发的异常:无法对 null 引用执行运行时绑定
今天上午运营反映有商户的账单没有生成. 查看日志,在批量生成账单服务执行过程中,因为如下异常而中断了: 跑批异常 Microsoft.CSharp.RuntimeBinder.RuntimeBinde ...
- oracle执行update语句时卡住问题分析及解决办法
转载:http://www.jb51.net/article/125754.htm 这篇文章主要介绍了oracle执行update语句时卡住问题分析及解决办法,涉及记录锁等相关知识,具有一定参考价值, ...
- Java基础:执行时异常和非执行时异常
1.Java异常机制 Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为全部异常的超类. Java中的异常分为两大类:错误Error和异常Exception.Jav ...
- Spring学习笔记——Spring事务仅仅对执行时异常回滚
我们在使用Spring时候一般都知道事务在遇到异常的时候会回滚.岂不知Spring的事务默认仅仅有在发生执行时异常即:RunTimeException时才会发生事务,假设一个方法抛出Exception ...
- alias导致virtualenv异常的分析和解法
title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...
- C++ 异常机制分析
C++异常机制概述 异常处理是C++的一项语言机制,用于在程序中处理异常事件.异常事件在C++中表示为异常对象.异常事件发生时,程序使用throw关键字抛出异常表达式,抛出点称为异常出现点,由操作系统 ...
- 自定义 ThreadPoolExecutor 处理线程运行时异常
自定义 ThreadPoolExecutor 处理线程运行时异常 最近看完了ElasticSearch线程池模块的源码,感触颇深,然后也自不量力地借鉴ES的 EsThreadPoolExecutor ...
- 服务网关zuul之二:过滤器--请求过滤执行过程(源码分析)
Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能: 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求. 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生成 ...
随机推荐
- [Swift]LeetCode564. 寻找最近的回文数 | Find the Closest Palindrome
Given an integer n, find the closest integer (not including itself), which is a palindrome. The 'clo ...
- 一串数字中,只有一个数字出现一次,其他数字都出现两次,查找出这个数字(python)(原创)
背景: 电话面试&手撕代码 2019.03.22 Mufasa 问题: 一串数字中,只有一个数字出现一次,其他数字都出现两次,查找出这个数字 条件: 这串数字是有序数 解决方法: 核心代码只有 ...
- SpringMVC接收json数组对象
最近帮一个妹子解决一个需求,就是前台使用ajax传三个相同的对象,再加一个form表单对象.然后遇到各种问题,终于解决了,@RequestBody接收Json对象字符串 以前,一直以为在Spring ...
- BBS论坛(二十七)
27.首页帖子列表布局完成 (1)apps/models.py 把帖子跟用户关联起来 class PostModel(db.Model): __tablename__ = 'post' id = db ...
- BBS论坛(六)
6.1.优化json数据的返回 (1)新建utils/restful.py # utils/restful.py from flask import jsonify class HttpCode(ob ...
- ionic4+angular6 混合移动开发 capacitor cordova
首先要更新或者安装 ionic cli npm install -g ionic 创建项目 ionic start ionic-angular tabs --type=angular –type=an ...
- Node.js API 初解读(三)
目录 Node.JS API 初解读三 Node.JS API 初解读三 Version: NodeJs v6.2.0 一. DNS (Domain Name Server) [域名服务器] 1.简介 ...
- Android Studio升级到3.1.4后打开旧项目警告:The `android.dexOptions.incremental` property is deprecated and it has no effect on the build process.
现象截图 问题原因&解决方案 在build.gralde中,对Android开发过程中突破的方法数的限制,做了如下解决配置: dexOptions { incremental true jav ...
- MaxCompute在高德大数据上的应用
2019年1月18日,由阿里巴巴 MaxCompute开发者社区和阿里云栖社区联合主办的“阿里云栖开发者沙龙大数据技术专场”走近北京联合大学,本次技术沙龙上,高德数据技术专家苗翌辰为大家分享了高德如何 ...
- 痞子衡嵌入式:ARM Cortex-M内核那些事(2)- 第一款微控制器
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是第一款Cortex-M微控制器. 1.天生荣耀:ARM Cortex-M处理器由来 ARM公司自2004年推出ARMv7内核架构时,摒弃 ...