mongodb采坑记录-number/numberlong

本文深入探讨了在使用MongoDB数据库存储长数字ID时遇到的问题,揭示了NumberLong数据类型的特点,以及如何正确地使用它进行查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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的类型的。
还有一个要说明的就是,列字段的数据类型,是根据列内最长的字段来决定的。。。

<think>嗯,用户在使用MongoDB的时候遇到了启动命令失败的问题。让我仔细看一下他的命令和错误信息。首先,用户执行的命令是: mongod --dbpath /usr/local/mongodb/data/ --config /usr/local/mongodb/mongodb.conf--logpath /usr/local/mongodb/log/mongodb.log --port 27017 然后报错说日志文件已存在,被移动了,但可能还有其他问题。用户以root身份执行,但可能权限有问题? 首先,我需要检查用户的命令格式是否正确。注意到在--config参数后面,路径和--logpath之间没有空格,这可能是个问题。用户写的是“--config /usr/local/mongodb/mongodb.conf--logpath”,中间应该有个空格,否则MongoDB会认为--logpath是配置文件路径的一部分,导致参数解析错误。这应该是主要问题所在。 然后,用户看到的错误信息是日志文件已存在,被重命名了。这可能是因为之前MongoDB正常关闭时没有删除日志文件,或者用户在启动时没有使用--fork参数在后台运行,导致控制台输出和日志文件的冲突?不过错误信息中的移动是正常行为,当检测到已有日志文件时,MongoDB会将其重命名备份,然后创建新的日志文件。但用户可能误以为这是错误,其实可能只是警告。 但问题在于,用户是否成功启动了服务?可能命令因为参数错误而未能正确执行。比如,当--config后面没有正确分隔参数时,MongoDB可能无法正确读取配置文件,导致后续参数被忽略或解析错误,从而启动失败。 另外,用户是否有权限访问指定的目录?比如,/usr/local/mongodb/data/、日志目录等,需要确保MongoDB进程有写入权限。如果用户使用root运行,可能没问题,但数据目录的权限是否正确?比如,如果之前是用其他用户创建的,可能导致权限问题。 接下来,可能的解决方案包括: 1. 修正命令中的参数分隔问题,确保每个选项之间有空格。 2. 检查配置文件中的设置是否与命令行参数冲突,比如是否在配置文件中指定了不同的dbpath或logpath。 3. 确保相关目录存在且有正确的权限。 4. 如果使用--config参数,可能需要确认配置文件中的内容是否正确,避免重复指定参数导致冲突。 5. 检查端口27017是否被其他进程占用。 6. 查看移动后的日志文件内容,确认是否有其他错误信息。 此外,用户可能没有使用--fork参数,导致进程在前台运行,如果控制台关闭,进程会终止。但用户的问题可能只是命令参数格式错误导致启动失败。 所以,首先应该让用户修正命令中的空格问题,然后检查目录权限和存在性。如果用户仍然遇到问题,可能需要进一步检查日志内容,或者配置文件的内容是否正确。</think>根据您提供的命令和错误信息,问题主要由参数格式错误和目录权限问题导致。以下是分步解决方案: --- ### **步骤1:修正命令格式错误** 您原始命令中`--config`和`--logpath`参数之间缺少空格,导致参数解析失败。正确命令应为: ```bash mongod --dbpath /usr/local/mongodb/data/ \ --config /usr/local/mongodb/mongodb.conf \ --logpath /usr/local/mongodb/log/mongodb.log \ --port 27017 ``` 👉 **关键修改**:在`--config`参数的值后添加空格,确保参数独立。 --- ### **步骤2:检查目录权限** MongoDB需要对数据、日志目录有**写入权限**。执行以下命令: ```bash # 创建目录(如果不存在) sudo mkdir -p /usr/local/mongodb/{data,log} # 赋予MongoDB用户(通常为mongodb)权限 sudo chown -R mongodb:mongodb /usr/local/mongodb sudo chmod -R 755 /usr/local/mongodb ``` --- ### **步骤3:验证配置文件内容** 如果使用了`--config`参数,需确保配置文件`mongodb.conf`与命令行参数**无冲突**。例如: ```yaml # /usr/local/mongodb/mongodb.conf storage: dbPath: /usr/local/mongodb/data/ systemLog: destination: file path: /usr/local/mongodb/log/mongodb.log logAppend: true net: port: 27017 ``` ⚠️ **注意**:配置文件中若已定义`dbPath`或`logpath`,命令行中需移除对应参数避免冲突。 --- ### **步骤4:以守护进程模式启动(推荐)** 添加`--fork`参数让MongoDB后台运行: ```bash mongod --dbpath /usr/local/mongodb/data/ \ --config /usr/local/mongodb/mongodb.conf \ --logpath /usr/local/mongodb/log/mongodb.log \ --port 27017 \ --fork ``` --- ### **步骤5:排查常见问题** 1. **端口冲突** 检查27017端口是否被占用: ```bash sudo lsof -i :27017 ``` 若被占用,终止相关进程或更换端口。 2. **日志分析** 查看日志文件内容,定位具体错误: ```bash tail -f /usr/local/mongodb/log/mongodb.log ``` --- ### **完整修复命令示例** ```bash # 确保目录存在并设置权限 sudo mkdir -p /usr/local/mongodb/{data,log} sudo chown -R $(whoami) /usr/local/mongodb # 若以当前用户运行 # 启动MongoDB(无配置文件时) mongod --dbpath /usr/local/mongodb/data/ \ --logpath /usr/local/mongodb/log/mongodb.log \ --port 27017 \ --fork ``` --- ### **总结** - **参数格式**:确保每个参数之间有空格。 - **目录权限**:MongoDB需对数据、日志目录有写入权限。 - **配置文件**:避免参数重复定义。 - **日志分析**:通过日志文件定位深层问题。 若问题仍存在,请提供`/usr/local/mongodb/log/mongodb.log`中的错误详情以便进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值