✅ 内置解决方案 isValidObjectId()
> Mongoose 5.7.12
如果您正在使用Mongoose,我们可以使用Mongoose内置的isValidObjectId来测试一个字符串是否为12字节或24个十六进制字符的字符串。
这就足以执行有效查询,而不会抛出任何无效的对象ID错误。
mongoose.isValidObjectId(string)
请注意!
isValidObjectId()
最常用于测试预期的 objectID,以避免出现 mongoose 抛出无效对象 ID 错误。
示例
if (mongoose.isValidObjectId("some 12 byte string")) {
return collection.findOne({ _id: "some 12 byte string" })
}
如果您不对预期的objectID进行有条件的测试,那么您将需要捕获错误。
try {
return collection.findOne({ _id: "abc" })
} 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个字符的十六进制字符串。
Note: I have translated the content into Chinese as per the request.
function checkObjectIdValid(id){ if(ObjectID.isValid(id)){ if(new ObjectID(id) === id){ return true } else { return false } } else { return false } }
- Jackson Vaughanconst ObjectId = require('mongoose').Types.ObjectId; function isObjectIdValid(id) { if (ObjectId.isValid(id)) { if (String(new ObjectId(id)) === id) { return true } else { return false } } else { return false } }
- marcvanderisObjectIdValid = id => ObjectId.isValid(id) ? String(new ObjectId(id) === id) ? true : false : false;
,意思是检查传入的id值是否为有效的ObjectID格式,如果是则返回true,否则返回false。 - Rod911