我可以确定字符串是否是MongoDB ObjectID吗?

时间:2012-12-13 00:01:14

标签: javascript node.js mongodb coffeescript express

我通过将字符串转换为BSON来进行MongoDB查找。在进行转换之前,有没有办法让我确定我拥有的字符串是否是Mongo的有效ObjectID?

这是我当前findByID函数的coffeescript。它工作得很好,但如果我确定字符串不是ID,我想通过不同的属性进行查找。

db.collection "pages", (err, collection) ->
  collection.findOne
    _id: new BSON.ObjectID(id)
  , (err, item) ->
    if item
      res.send item
    else
      res.send 404

17 个答案:

答案 0 :(得分:82)

我发现mongoose ObjectId验证器可以验证有效的objectIds,但我发现了一些无效ID被认为有效的情况。 (例如:任何12个字符长的字符串)

var ObjectId = require('mongoose').Types.ObjectId;
ObjectId.isValid('microsoft123'); //true
ObjectId.isValid('timtomtamted'); //true
ObjectId.isValid('551137c2f9e1fac808a5f572'); //true

为我工作的是将一个字符串转换为objectId,然后检查原始字符串是否与objectId的字符串值匹配。

new ObjectId('timtamtomted'); //616273656e6365576f726b73
new ObjectId('537eed02ed345b2e039652d2') //537eed02ed345b2e039652d2

这项工作是因为有效ID在转换为ObjectId时不会改变,但是获取false有效的字符串在转换为objectId时会发生变化。

答案 1 :(得分:64)

您可以使用正则表达式来测试:

的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    
}

答案 2 :(得分:7)

我过去曾使用本机节点mongodb驱动程序执行此操作。 isValid方法检查该值是否为有效的BSON ObjectId。 See the documentation here.

var ObjectID = require('mongodb').ObjectID;
console.log( ObjectID.isValid(12345) );

答案 3 :(得分:3)

以下是我根据@ andy-macleod的答案撰写的一些代码。

它可以是int或string或ObjectId,如果传递的值有效则返回有效的ObjectId,如果无效则返回null:

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;
}

答案 4 :(得分:3)

如果您使用的是Mongoose,我们可以使用isValidObjectId来测试String是12个字节还是24个十六进制字符的字符串。

mongoose.isValidObjectId(string)将返回true / false

这是accepted solution提供的升级解决方案。

答案 5 :(得分:1)

使用 mongodb 模块检查字符串是否为有效的Mongo ObjectId的最简单方法。

const ObjectID = require('mongodb').ObjectID;

if(ObjectID.isValid(777777777777777)){
   console.log("Valid ObjectID")
}

答案 6 :(得分:1)

下面是一个函数,它使用ObjectId isValid方法检查new ObjectId(id)是否返回相同的值。在选择的答案中,安迪·麦克劳德(Andy Macleod)很好地描述了isValid一个人不够的原因。

const ObjectId = require('mongoose').Types.ObjectId;

/**
 * True if provided object ID valid
 * @param {string} id 
 */
function isObjectIdValid(id){ 
  return ObjectId.isValid(id) && new ObjectId(id) == id;
}

答案 7 :(得分:0)

这种方法可能对某人有所帮助。它适用于 nodejs mongodb 驱动程序

if (ObjectId.isValid(stringId) && (ObjectId(stringId).toString() === stringId)){
  // your operation
}

答案 8 :(得分:0)

@ ross-u的答案太神奇了。

我已经链接了方法以进行完整的内联验证:

documentId = id && isValid(id) && new ObjectId(id) == id ? id : null

请注意,双等号非常重要,因为new ObjectId()不会返回字符串,并且与普通字符串(按照我的逻辑)相比,严格比较将返回false。

方法已从require暴露的mongoose对象中解构:

const {
  Types: {
    ObjectId: { isValid },
    ObjectId
  }
} = require("mongoose");

答案 9 :(得分:0)

solution答案中,安迪·麦克劳德(Andy Macleod)说:

一直在为我工作的是将字符串强制转换为objectId和 然后检查原始字串是否与 objectId。

new ObjectId('timtamtomted'); //616273656e6365576f726b73
new ObjectId('537eed02ed345b2e039652d2') //537eed02ed345b2e039652d2

这项工作是因为有效ID强制转换为ObjectId时不会更改 但是当字符串转换为 objectId。

此方法的实现将是一个函数,用于检查传递的值是否为有效的ObjectId并与stringObjectId(对象)值一起使用。看起来像这样:

var ObjectId = require("mongoose");.Types.ObjectId;

function isValidObjectId(value) {
  // If value is an object (ObjectId) cast it to a string
  var valueString = typeof value === "string" ? value : String(value); 

  // Cast the string to ObjectId
  var idInstance = new ObjectId(valueString); 

  return String(idInstance) === valueString;
}

答案 10 :(得分:0)

最简单的方法基本上是将您的ObjectId方法包装在try and catch服务中。 然后,您将使用此服务来处理Objecet ID,而不是直接使用该方法:

var ObjectId = REQUIRE OR IMPORT ...

// service
function oid(str) {
 try {   
   return ObjectId(str);
 } catch(err) {
   return false;
 }
}

// usage
if (oid(USER_INPUT)) {
  // continue
} else {
  // throw error
}

您还可以发送null或空道具以获取新生成的ID。

答案 11 :(得分:0)

mongoose.Types.ObjectId.isValid(string)如果字符串包含12个字母,则始终返回True

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

答案 12 :(得分:0)

我发现的唯一方法是使用我想要检查的值创建一个新的ObjectId,如果输入等于输出,则id有效:

[input]
eGalax = hidinput,/dev/input/event1,rotation=90,min_abs_x=60,min_abs_y=90,max_abs_x=1985,max_abs_y=1970

答案 13 :(得分:0)

对于mongoose,使用isValid()函数检查objectId是否有效

示例:

var ObjectId = mongoose.Types.ObjectId;
if(ObjectId.isValid(req.params.documentId)){
   console.log('Object id is valid'); 
}else{
   console.log('Invalid Object id');
}

答案 14 :(得分:0)

我花了一些时间来获得一个有效的解决方案,因为@Andy Macleod提出的将objectId值与其自己的字符串进行比较的方法正在崩溃Express.js服务器:

var view_task_id_temp=new mongodb.ObjectID("invalid_id_string"); //this crashed

我只是用一个简单的尝试来解决这个问题。

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
}

答案 15 :(得分:0)

If you have the hex string you can use this:

ObjectId.isValid(ObjectId.createFromHexString(hexId));

答案 16 :(得分:-1)

警告:对于以有效十六进制数字开头的任意12/24长度字符串, isValid 将返回 true 。 目前我认为这是一个更好的检查:

  

((thing.length === 24 || thing.length === 12) && isNaN(parseInt(thing,16)) !== true)