文章目录
一、Objectid的概述
ObjectID是MongoDB文档的默认主键,它是一个由12个字节组成的字符串表示,可以自动生成。一个ObjectID代表了一个MongoDB文档的ID(唯一标识符)。ObjectID的结构就是一个24个字符的十六进制字符串。
二、Objectid的结构
ObjectID由12个字节组成,其中:
- 4个字节是 Unix 时间戳(精确到秒,而不是毫秒)。
- 3个字节是客户端机器的唯一标识符,一般是机器的 MAC 地址。
- 2个字节是由进程 PID(进程标识符)生成的随机数。
- 3个字节由随机数生成。
ObjectID的格式十六进制字符串,例如:“507f1f77bcf86cd799439012”。
三、Objectid的用途
ObjectID是 MongoDB 中文档的默认主键。每个文档都必须有一个唯一的ObjectID作为主键,以便在文档进行复制或者分区的时候能够明确区分哪些文档是相同的。
在创建索引的时候,也可以指定ObjectID字段作为索引键。
在编写代码时,对查询结果排序时,可以按照ObjectID中的时间戳进行排序。
四、 Objectid在python中的使用
1、生成一个Objectid
同一个进程下,生成一个默认ObjectId,每次生成的时间部分是实时的,机器码和pid部分固定不变,inc部分是自增的。只有这种方法影响inc的自增,其他方法不会。
>>> from bson.objectid import ObjectId
>>> ObjectId()
ObjectId('62a9cbca21046f32ccd52268')
>>> ObjectId()
ObjectId('62a9d12c21046f32ccd52269')
2、指定生成Objectid
>>> ObjectId('62a9cbca21046f32ccd52268')
ObjectId('62a9cbca21046f32ccd52268')
3、依据时间来生成Objectid
可以根据时间来生成,可以用来根据时间对MongoDB的_id做范围筛选
>>> import datetime
>>> gen_time = datetime.datetime(2010, 1, 1)
>>> dummy_id = ObjectId.from_datetime(gen_time)
>>> dummy_id
ObjectId('4b3d3b000000000000000000')
>>> result = collection.find({"_id": {"$lt": dummy_id}})
4、obj.binary来生成ObjectId
>>> a = ObjectId()
>>> a
ObjectId('62a9d5d421046f32ccd5226e')
>>> a.binary
'b\xa9\xd5\xd4!\x04o2\xcc\xd5"n'
>>> ObjectId('b\xa9\xd5\xd4!\x04o2\xcc\xd5"n')
ObjectId('62a9d5d421046f32ccd5226e')
>>> ObjectId(b'foo-bar-quux')
ObjectId('666f6f2d6261722d71757578')
5、判断是否是ObjectId对象
is_valid可以判断是否为ObjectId对象,_inc是自增3个字节转为数字后的结果,_machine_bytes是机器的bytes。
ObjectId还可以相互做比较
@classmethod
def is_valid(cls, oid):
pass
>>> ObjectId.is_valid(a)
True
>>> a.binary
'b\xa9\xd5\xd4!\x04o2\xcc\xd5"n'
>>> a.generation_time
datetime.datetime(2022, 6, 15, 12, 51, 32, tzinfo=<bson.tz_util.FixedOffset object at 0x0000000003D2DFC8>)
>>> a._inc
13967983
>>> hex(a._inc)
'0xd5226f'
>>> a._machine_bytes
'!\x04o'
>>> a = ObjectId()
>>> a
ObjectId('62a9e11421046f32ccd5226f')
>>> b = ObjectId(a)
>>> a == b
True
>>> a is b
False
>>> a < ObjectId()
True
五、使用pymong将数据导
def custom_encoder(obj):
if isinstance(obj, bytes):
return obj.decode('utf-8') # 将bytes对象转换为utf-8编码的字符串
elif isinstance(obj, datetime):
return obj.isoformat() # 将datetime对象转换为ISO 8601日期字符串
elif isinstance(obj, ObjectId): # 将ObjectID对象转换为字符串
return obj.__str__()
raise TypeError("Object of type '%s' is not JSON serializable" % type(obj))
# json序列化时加上default=custom_encoder
f_ow.write(json.dumps(line, default=custom_encoder) + '\n')