【知识小课堂】 mongodb 之 objectId
来源:互联网 发布:网络直播设备清单 编辑:程序博客网 时间:2024/06/10 18:58
一、OBJECTID
因公司开发人员在使用MONGODB时,总遇到一些小问题。为了增加大家的mongodb 数据库知识。
决定每周进行一、两次的知识小课堂。这里把内容整理出来,上传到博客中。也算是自己的一个mongodb 历程吧
1.1 结构
ObjectId("52cbab42231dea1e819b2a37"),
ObjectId("52cbab5b231dea1e819b2a38"),
ObjectId("52cbab70231dea1e819b2a39"),
52cbab70 时间戳
231dea 机器号
1e81 进程ID
9b2a39 自增数
以上数字为 16进制表示
特点:
1.24个16进制数据,使用 12字节的存储空间。
2.最后3个字节为:自动增长。可确保每秒生成的值也不一样,一秒最多允许每个进程拥有256^3个不同ObjectId
(后面3位16进制存在量可以达到: 16,777,216
也可以从存储量计算出来 FFFFFF 转换成10进制就是16,777,215)
3.可转移到客户端生成,而减轻服务器负担(需要客户端的驱动程序)
下面介绍几个相关的函数
>> x=ObjectId()ObjectId("53b3a89bf988c39955a30f9e")> xObjectId("53b3a89bf988c39955a30f9e")>x.str53b3a89bf988c39955a30f9e> x.toString()ObjectId("53b3a89bf988c39955a30f9e")> x.getTimestamp()ISODate("2014-07-02T06:37:15Z")> x.valueOf()53b3a89bf988c39955a30f9e>
函数说明:
1.Str 功能 与valueOf()相同
2.toString() 把一个对象转换成
了一字串。这时两个objectId可以对比。
3.getTimestamp() 抽取 时间
我们再来看看一个有意思的查询:
既然可以把从objectId 获取日期,那我是否可以使用一个日期做为条件,使用_id 字段来进行查询呢。
我的方法是
<span style="font-size:18px;">> a = db.order.findOne(){"_id" : ObjectId("5331128631a4804b226471e4"),"md5" : "cacae8722c325d62e795e5c273d5f49b", ……}> a."_id"Wed Jul 2 14:50:57.494 SyntaxError: Unexpected string> a._id.getTimestamp()ISODate("2014-03-25T05:22:14Z")> new Date("2014,03,25")ISODate("2014-03-24T16:00:00Z")> new Date("2014,03,25")ISODate("2014-03-24T16:00:00Z")> db.order.find({"_id.getTimestamp()":{$gt:new Date("2014,03,25")}}).count()0> db.order.find({_id.getTimestamp():{$gt:new Date("2014,03,25")}}).count()Wed Jul 2 14:54:00.298 SyntaxError: Unexpected token .> </span>
可以看到,看来是行不通。mongodb 无法识别 处理后的字段。
那只能自己生成一个objectId 再进行对比了。
我以前一直以为是无法进行两个 objectId 来进行对比的。
但查询了官方资料。并没有看到相关按时间生成新的objectID 的方法/函数。
(http://docs.mongodb.org/manual/reference/method/)
后来找到了开发牛人的一个便方,解决了此问题。代码如下:
<span style="font-size:18px;">#构建一个指定日期的objectId()> var timestamp = Math.floor(new Date(2014,03,01).getTime() / 1000); #getTime() 返回毫秒数> var hex = (‘00000000’ + timestamp.toString(16)).substr(-8); #前填充0> var v_objectId = new ObjectId(hex + new ObjectId().str.substring(8)); #更换掉前面的时间值</span>
其它方法也比较简单,就是把一个日期转换成16进制后,替换到一个新生成的objectId 中去。
当自己构造好一个objectId后,后面我们来使用它进行查询:
<span style="font-size:18px;">#用objectId() 来进行对比查询> db.order.find({_id:{$gt:v_objectId}}){ "_id" : ObjectId("533e1049e4271af009000005"), "md5" : "a99038f392284b7dac895dc0030486c8",... }</span>
可以看到,查询结果出来了。从上面可以看出。两个objectId 是可以进行对比的。
从上面示例代码看到
虽然可以从ojbectId 中提取一些信息。但如果要使用 objectid中的信息来做为查询条件,相对还是比较麻烦的。
就象我上面的,如果我要从objectID 的建立日期 来做为查询条件,我自己得先用查询时间构建一个objectID,然后再进行查询。
如果查询条件还有范围什么的。还不如再建立一个字段create_dt 来保存记录的建立时间。以后查询统计用此字段,还更方便。
我们再来看看查询的计划,看到已使用了索引,此计划虽然不能说明什么。但也可以让我知道是用_id 字段的索引。
<span style="font-size:18px;">> db.order.find({_id:{$gt:v_objectId}}).explain(){"cursor" : "BtreeCursor _id_","isMultiKey" : false,"n" : 3,"nscannedObjects" : 3,"nscanned" : 3,"nscannedObjectsAllPlans" : 3,"nscannedAllPlans" : 3,"scanAndOrder" : false,"indexOnly" : false,"nYields" : 0,"nChunkSkips" : 0,"millis" : 0,"indexBounds" : {"_id" : [[ObjectId("533991005c1e4132ccbaf755"),ObjectId("ffffffffffffffffffffffff")]]},"server" : "localhost.localdomain:27017"}> </span>
- 【知识小课堂】 mongodb 之 objectId
- 【知识小课堂】mongodb 之 查询关键词使用
- 【知识小课堂】mongodb 之 特殊集合及索引
- MongoDB深究之ObjectId
- MongoDB深究之ObjectId
- MongoDB深究之ObjectId
- MongoDB深究之ObjectId
- MongoDB深究之ObjectId
- MongoDB深究之ObjectId
- 【知识小课堂】 mongodb 之字段中的【 数组】、【内嵌文档】
- 【知识小课堂】4 之 索引
- 【知识小课堂】 之 聚合函数
- mongodb ObjectId
- MongoDB:18-MongoDB-ObjectId
- MongoDB小技巧-用ObjectID查询某一时间范围内的数据
- java 课堂小知识总结
- java 课堂小知识总结
- MongoDB ObjectId的优化
- c语言通讯录管理系统
- node.js代理设置
- left join 用法
- 简单java bean对象转换(不支持复杂对象的克隆)
- 中国长城防火墙(GFW)背后的数据
- 【知识小课堂】 mongodb 之 objectId
- MyEclipse中创建Maven工程
- 制作精灵遮罩cocos2dx3.0
- android之BaseAdapter的使用,加深引用对象理解
- 在iOS中创建静态库
- 不用清扫!扫地机器人伴你畅享“世界杯”!
- C 语言模仿实现HashTable
- arcgis api for silverlight
- 交叉编译器环境变量的设置问题