【Mongo】MongoDb的_id生成规则
MongoDB的文档必须有一个_id键。
目的是为了确认在集合里的每个文档都能被唯一标识。
ObjectId 是 _id 的默认类型。
ObjectId 采用12字节的存储空间,每个字节两位16进制数字,是一个24位的字符串。 12位生成规则: [0,1,2,3] [4,5,6] [7,8] [9,10,11] 时间戳 |机器码 |PID |计数器 前四字节是时间戳,可以提供秒级别的唯一性。 接下来三字节是所在主机的唯一标识符,通常是机器主机名的散列值。 接下来两字节是产生ObjectId的PID,确保同一台机器上并发产生的ObjectId是唯一的。
最后三字节是自增计数器,确保相同进程同一秒钟产生的ObjectId是唯一的。
前九字节保证了同一秒钟不同机器的不同进程产生的ObjectId时唯一的。
由此可得,在对数据库数据进行排序/查询时,可以直接根据_id来进行排序/查询(因为生成规则前四字节是时间戳,有秒级的唯一性)
代码示例:
//举例说明:例如要查询 30天之前的一整天的mongo记录 public static void main(String[] args) throws ParseException { LocalDateTime ltDate = LocalDateTime.now().plusDays(-30); LocalDateTime gtDate = LocalDateTime.now().plusDays(-29); System.out.println("ltDate:" + ltDate); System.out.println("gtDate:" + gtDate); String ltDateTimeStampHex = mongoIdHandler(getDate(ltDate)); System.out.println("$lt:" + ltDateTimeStampHex); String gtDateTimeStampHex = mongoIdHandler(getDate(gtDate)); System.out.println("$gt:" + gtDateTimeStampHex); BasicDBObject cond = new BasicDBObject(); //_id的查询条件是时间 BasicDBObject time = new BasicDBObject(); cond.put("_id", time); time.put("$lt", new ObjectId(ltDateTimeStampHex)); time.put("$gt", new ObjectId(gtDateTimeStampHex)); } private static Date getDate(LocalDateTime localDateTime){ ZoneId zone = ZoneId.systemDefault(); Instant instant = localDateTime.atZone(zone).toInstant(); java.util.Date date = Date.from(instant); return date; } /** * 根据时间获取秒,根据秒转化16进制,再补16个0 补齐24位 * * @param date 日期 * @return {@link String} */ private static String mongoIdHandler(Date date) { //获取秒 long secondTimstamp = date.getTime() / 1000; //将秒转换为16进制 String strHex = Long.toHexString(secondTimstamp); //将16进制后边补充16个0 String _id = strHex + "0000000000000000"; return _id; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2022-07-26 【sql】【String.format】自动补0【alter】mysql分表情况下新增一列不为空的列
2016-07-26 【hibernate 执行方法未插入数据库】hibernate的save方法成功执行,但是未插入到数据库