相关文章推荐
失落的勺子  ·  [VBA] ...·  1 年前    · 
眼睛小的铁链  ·  Debug high CPU usage ...·  1 年前    · 
知识渊博的橡皮擦  ·  Unity接入Google ...·  1 年前    · 

mongodb采坑之路-number/numberlong

mongodb作为优秀的文件存储数据库,既能向redis一样实现轻量级的缓存,又能作为百万、千万级的数据储存,还有灵活的NOSQL及内置mapreduce功能,当然在多节点分片应用的场景下,又能提供绝对高于redis的性能优势,在项目应用中已经越来越多。
从15年左右开始逐步接触mongodb,到现在已经有4-5年的使用经验了,然而今天碰到的这个大坑,硬生生的的折腾了我好几个小时。。。。下面把这段囧经历分享一下,让大家开心一下。

目前公司有需求需要重构一个项目,其中包括数据库的重构以及在项目中增加缓存的使用,当然由于数据级别比较大,而且涉及政府项目中间很可能过网闸,为了最大限度的提升前端应用响应速度,这里我选用mongodb在网闸前段应用增加缓存,避免大量数据通过网闸进行交互,以此提升高并发性能。
缓存信息之一即是用户表,原用户表采用了***19位数字ID***。
PS:为啥是19位数字ID咱表示也不知道
啧啧啧~如下图,那个123开头的就是之前的19位数字ID,这个ID有
那么长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长
在这里插入图片描述
接下来。根据ID查询数据。
那么我们写入第一个查询语句。=就是这个比较长的啦。。

db.personHealthCode.find({_id:1234386662595891200});

在这里插入图片描述
不出所料-直接就查出来了。。
那么我们写入第二个查询语句。=当然就是这个比较短的了。。

db.personHealthCode.find({_id:39529165196514388});

在这里插入图片描述
**WTF~~~~~~!!!你看的没错。。啥也没有。。**
没办法,我开启了怀疑模式。。。难道这个ID不是NUMBER?
于是乎

db.personHealthCode.find({_id:"39529165196514388"});
db.personHealthCode.find({"_id":39529165196514388});
db.personHealthCode.find({"_id":"39529165196514388"});

加的我连代码都不会写了。。。。。然而依然查不出来。。。。。。
再次于是乎😅😅😅😅😅那么就来看看这个字段到底是啥数据类型吧*****
在这里插入图片描述
直接查询ID类型是number的,妥妥的有值,然后又查ID大于小于一个既有值之间的数据。依然妥妥的有值…………
然后表示现在我心理慌的一B啊。。。😀😀😀😀😀😀

继续发动脑细胞 ヾ(o◕∀◕)ノヾ仔细的想。。。。这TM到底是个什么数据类型。。。。怎么就查不到。。

。。。再次确认是NUMBER没有错~!!!!!!!!!!!!!!!!!!!

到此为止,我已经深深的怀疑,这是数据库的BUG!!!BUG!!!!,因为目前使用的是3.6社区版本,于是俺准备找个4.X版🙏🙏🙏🙏🙏🙏🙏,保佑。。4.X可千万别出问题。。把数据搞进去试试。。。
那么第一步。。。备份数据吧。。
在这里插入图片描述

于是乎。。让我发现了一个惊天😱😱😱😱😱😱😱😱的秘密 。。这货居然是numberlong。。那么推断一下,,,直接强转就完了呗😁。。。

就有了如下代码

db.personHealthCode.find({_id:NumberLong('39529165183456143')});
db.personHealthCode.find({_id:NumberLong('1234352405546668032')});

果然。。数据就这么轻轻松松的查了出来。。。。。。。。

PS:最后推测一下原因,因为长ID超过了19位,而对于这么长的数字,mongo认为自己很智能的运算会把他自认为是numberlong类型,这样即使不加numberlong的强制转换,也可以查询出来,而对于比较短的id,再进行find操作的时候,mongo会认为他是Number,那么是无法查询出来本身是Numberlong的类型的。
还有一个要说明的就是,列字段的数据类型,是根据列内最长的字段来决定的。。。

这种数据类型必须要在NumberLong对象里面加上双引号,才能执行正常查询动作。db.t_element_access_reason.find( { "sessionId" : NumberLong("6421359123204194756") } ) java通过如下方式取出MongoDB记录 //其中,arr为存放Documnet的ArrayList对象 String qJson=arr.get(i).toJson(); //将documen转为json字符 RecvHead recvHead = JSONO 将MongodbNumberlong类型转String类型方法 本文介绍将.CSV文件数据导入到Mongodb数据库后,Numberlong类型数据如何转换为String类型数据。 电脑配置:windows7 64位 Mongodb:3.2. 电脑配置:windows7 64位 NumberLong(x)超出其限制值并四舍五入,而NumberLong("x")没有。现在,我们将看一个数字,并将其用于NumberLong(x)和NumberLong("x")来查看差异。让我们创建一个包含文档的集合->db.demo603.insert({"longValue":NumberLong(988998985857575789)});WriteResult({"nIn... MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。 它支持的数据结构非常松散,是一种类似于JSON 的 格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。... NumberLongNumberInt是在MongoDB的壳的MongoDBJavaScript函数不数据类型。 MongoDB中号码存储为类型0×01(浮点),类型为0x10(32位整数)或类型0×12(64位整数)。如果您在MongoDB shell中插入或更新文档,那么NumberLong将创建一个64位整数,NumberInt将创建一个32位整数,并且一个常规JavaScript编号将... 1、findOne查询数据今天使用mongodb的findOne查询数据,发现怎么也查不出来了开始的时候使用的是id查询 id为数字,查不出来后来改成另一个字段,是字符串,查出来了于是回到id查询,将查询条件改成{id: Number(id)} 就可以了原因可能是我的id是从url中获取的,所以默认就是字符串的格式了,转成数字就好了。2、find查询数据ongodb中查询数据常用的是find()例...