Подтвердить что ты не робот

Могу ли я определить, является ли строка идентификатором объекта MongoDB?

Я делаю поиск MongoDB, преобразовывая строку в BSON. Есть ли способ определить, имеет ли строка, которая у меня есть, действительный ObjectID для Mongo перед выполнением преобразования?

Вот кофейник для моей текущей функции findByID. Он отлично работает, но я хотел бы искать другой атрибут, если я определяю, что строка не является идентификатором.

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

Ответ 1

Я обнаружил, что проверщик валидации Mongoose ObjectId работает для проверки правильных объектов, но я обнаружил несколько случаев, когда неверные идентификаторы считались действительными. (например: любая строка длиной 12 символов)

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

То, что работает для меня, - это литье строки в objectId, а затем проверка того, что исходная строка соответствует строковому значению объекта.

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

Эта работа, потому что действительные идентификаторы не изменяются при передаче в ObjectId, но строка, которая получает ложное значение, будет изменяться при нажатии на объект.

Ответ 2

Для этого можно использовать регулярное выражение:

CoffeeScript

if id.match /^[0-9a-fA-F]{24}$/
    # it an ObjectID
else
    # nope

JavaScript

if (id.match(/^[0-9a-fA-F]{24}$/)) {
    // it an ObjectID    
} else {
    // nope    
}

Ответ 3

Я использовал собственный драйвер node mongodb для этого в прошлом. Метод isValid проверяет, является ли значение действительным объектом BSON ObjectId. См. документацию здесь.

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

Ответ 4

Вот какой код я написал на основе ответа @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;
}

Ответ 5

Если у вас есть шестнадцатеричная строка, вы можете использовать это:

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

Ответ 6

Мне потребовалось некоторое время, чтобы получить правильное решение, поскольку тот, который предложил @Andy Macleod для сравнения значения objectId со своей собственной строкой, разбивал сервер Express.js на:

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

Я просто использовал простой try catch, чтобы решить эту проблему.

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

Для 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');
}

Ответ 8

Единственный способ, который я нашел, - это создать новый ObjectId со значением, которое я хочу проверить. Если вход равен выводу, идентификатор действителен:

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) всегда возвращает True, если строка содержит 12 букв

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

Самый простой способ - это обернуть ваш метод ObjectId в службу try and catch. Затем вы используете этот сервис для обработки идентификаторов Objecet, вместо того, чтобы использовать метод напрямую:

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
}

Вы также можете отправить пустой или пустой реквизит, чтобы получить новый сгенерированный идентификатор.

Ответ 11

Предупреждение: isValid вернет true для произвольных строк длины 12/24, начиная с действительной шестнадцатеричной цифры. В настоящее время я думаю, что это лучше проверить:

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