可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am doing MongoDB lookups by converting a string to BSON. Is there a way for me to determine if the string I have is a valid ObjectID for Mongo before doing the conversion?
Here is the coffeescript for my current findByID function. It works great, but I'd like to lookup by a different attribute if I determine the string is not an ID.
db.collection "pages", (err, collection) ->
collection.findOne
_id: new BSON.ObjectID(id)
, (err, item) ->
if item
res.send item
else
res.send 404
回答1:
I found that the mongoose ObjectId validator works to validate valid objectIds but I found a few cases where invalid ids were considered valid. (eg: any 12 characters long string)
var ObjectId = require('mongoose').Types.ObjectId;
ObjectId.isValid('microsoft123'); //true
ObjectId.isValid('timtomtamted'); //true
ObjectId.isValid('551137c2f9e1fac808a5f572'); //true
What has been working for me is casting a string to an objectId and then checking that the original string matches the string value of the objectId.
new ObjectId('timtamtomted'); //616273656e6365576f726b73
new ObjectId('537eed02ed345b2e039652d2') //537eed02ed345b2e039652d2
This work because valid ids do not change when casted to an ObjectId but a string that gets a false valid will change when casted to an objectId.
回答2:
You can use a regular expression to test for that:
CoffeeScript
if id.match /^[0-9a-fA-F]{24}$/
# it's an ObjectID
else
# nope
JavaScript
if (id.match(/^[0-9a-fA-F]{24}$/)) {
// it's an ObjectID
} else {
// nope
}
回答3:
I have used the native node mongodb driver to do this in the past. The isValid method checks that the value is a valid BSON ObjectId. See the documentation here.
var ObjectID = require('mongodb').ObjectID;
console.log( ObjectID.isValid(12345) );
回答4:
Here is some code I have written based on @andy-macleod's answer.
It can take either an int or string or ObjectId and returns a valid ObjectId if the passed value is valid or null if it is invalid:
var ObjectId= require('mongoose').Types.ObjectId;
function toObjectId(id) {
var stringId = id.toString().toLowerCase();
if (!ObjectId.isValid(stringId)) {
return null;
}
var result = new ObjectId(stringId);
if (result.toString() != stringId) {
return null;
}
return result;
}
回答5:
If you have the hex string you can use this:
ObjectId.isValid(ObjectId.createFromHexString(hexId));
回答6:
It took me a while to get a valid solution as the one proposed by @Andy Macleod of comparing objectId value with its own string was crashing the Express.js server on:
var view_task_id_temp=new mongodb.ObjectID("invalid_id_string"); //this crashed
I just used a simple try catch to solve this.
var mongodb = require('mongodb');
var id_error=false;
try{
var x=new mongodb.ObjectID("57d9a8b310b45a383a74df93");
console.log("x="+JSON.stringify(x));
}catch(err){
console.log("error="+err);
id_error=true;
}
if(id_error==false){
// Do stuff here
}
回答7:
For mongoose , Use isValid() function to check if objectId is valid or not
Example :
var ObjectId = mongoose.Types.ObjectId;
if(ObjectId.isValid(req.params.documentId)){
console.log('Object id is valid');
}else{
console.log('Invalid Object id');
}
回答8:
The only way i found is to create a new ObjectId with the value i want to check, if the input is equal to the output, the id is valid :
function validate(id) {
var valid = false;
try
{
if(id == new mongoose.Types.ObjectId(""+id))
valid = true;
}
catch(e)
{
valid = false;
}
return valid;
}
> validate(null)
false
> validate(20)
false
> validate("abcdef")
false
> validate("5ad72b594c897c7c38b2bf71")
true
回答9:
mongoose.Types.ObjectId.isValid(string) always returns True if string contains 12 letters
let firstUserID = '5b360fdea392d731829ded18';
let secondUserID = 'aaaaaaaaaaaa';
console.log(mongoose.Types.ObjectId.isValid(firstUserID)); // true
console.log(mongoose.Types.ObjectId.isValid(secondUserID)); // true
let checkForValidMongoDbID = new RegExp("^[0-9a-fA-F]{24}$");
console.log(checkForValidMongoDbID.test(firstUserID)); // true
console.log(checkForValidMongoDbID.test(secondUserID)); // false
回答10:
Warning: isValid will return true for arbitrary 12/24 length strings beginning with a valid hex digit.
Currently I think this is a better check:
((thing.length === 24 || thing.length === 12) && isNaN(parseInt(thing,16)) !== true)