✅ 内置解决方案isValidObjectId()
> Mongoose 5.7.12
如果您使用的是 Mongoose,我们可以使用 mongoose内置的 isValidObjectId来测试 String 是 12 字节还是 24 十六进制字符的字符串。
mongoose.isValidObjectId(string); /* will return true/false */
请注意!
isValidObjectId()
最常用于测试预期的 objectID,以避免 mongoose throwing invalid object ID 错误。
例子
if (mongoose.isValidObjectId("some 12 byte string")) {
return collection.findOne({ _id: "some 12 byte string" })
// returns null if no record found.
}
如果您不有条件地测试预期的 objectID 是否有效,则需要捕获错误。
try {
return collection.findOne({ _id: "abc" })
//this will throw error
} catch(error) {
console.log('invalid _id error', error)
}
因为findOne({ _id: null })
和findOne({ _id: undefined })
是完全有效的查询(不会抛出错误),isValidObjectId(undefined)
并且isValidObjectId(null)
将返回 true。
注意2!
123456789012可能看起来不像一个 bson 字符串,但它完全是一个有效的 ObjectID,因为以下查询不会引发错误。(如果没有找到记录,则返回 null)。
findOne({ _id: ObjectId('123456789012')}) // ✅ valid query
313233343536373839303132可能看起来像一个 24 个字符的字符串(它是123456789012的十六进制值),但它也是一个有效的 ObjectId,因为以下查询不会引发错误。(如果没有找到记录,则返回 null)
findOne({ _id: ObjectId('313233343536373839303132')}) // ✅ valid query
以下内容无效(比上述示例少 1 个字符串字符)
findOne({ _id: ObjectId('12345678901')}) // ❌ not 12 byte string
findOne({ _id: ObjectId('31323334353637383930313')}) // ❌ not 24 char hex
ObjectId 的格式
ObjectId 很小,可能是唯一的,生成速度快,并且是有序的。ObjectId 值的长度为 12 个字节,包括:
- 一个 4 字节的时间戳值,表示 ObjectId 的创建,以 Unix 纪元以来的秒数为单位
- 每个进程生成一次的 5 字节随机值。这个随机值对于机器和过程是唯一的。
- 一个 3 字节递增计数器,初始化为随机值
由于上述随机值,无法计算ObjectId 。它只能显示为 12 字节字符串或 24 字符十六进制字符串。