Я выполняю поиск в MongoDB, преобразовывая строку в BSON. Есть ли способ определить, является ли имеющаяся у меня строка действительным идентификатором объекта для Mongo, прежде чем выполнять преобразование?
Вот coffeescript для моей текущей функции findByID. Он отлично работает, но я хотел бы выполнить поиск по другому атрибуту, если я определю, что строка не является идентификатором.
db.collection "pages", (err, collection) ->
collection.findOne
_id: new BSON.ObjectID(id)
, (err, item) ->
if item
res.send item
else
res.send 404
Ответы:
Я обнаружил, что валидатор mongoose ObjectId работает для проверки допустимых идентификаторов объектов, но я обнаружил несколько случаев, когда недопустимые идентификаторы считались действительными. (например: любая длинная строка из 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
Это работает, потому что действительные идентификаторы не меняются при преобразовании в ObjectId, но строка, которая получает ложный действительный идентификатор, изменится при преобразовании в objectId.
источник
function checkObjectIdValid(id){ if(ObjectID.isValid(id)){ if(new ObjectID(id) === id){ return true } else { return false } } else { return false } }
const 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 } }
es6
вам это:isObjectIdValid = id => ObjectId.isValid(id) ? String(new ObjectId(id) === id) ? true : false : false;
Вы можете использовать регулярное выражение, чтобы проверить это:
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 }
источник
lol456712bbfghLLsdfr
Раньше для этого я использовал собственный драйвер узла mongodb. Метод isValid проверяет, является ли значение допустимым BSON ObjectId. См. Документацию здесь.
var ObjectID = require('mongodb').ObjectID; console.log( ObjectID.isValid(12345) );
источник
ObjectId
, а неObjectID
. :)Если вы используете Mongoose, мы можем проверить, имеет ли строка 12 байтов или строку из 24 шестнадцатеричных символов, используя встроенный в mongoose isValidObjectId .
Это обновленное решение, предоставленное принятым решением .
источник
Вот код, который я написал на основе ответа @andy-macleod.
Он может принимать либо int, либо строку, либо 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; }
источник
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
источник
Единственный способ, который я нашел, - это создать новый 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
источник
Самый простой способ - обернуть ваш метод ObjectId в службу «попробуй и поймай». Затем вы используете эту службу для обработки идентификаторов 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 }
Вы также можете отправить пустые или пустые реквизиты, чтобы получить новый сгенерированный идентификатор.
источник
Самый простой способ проверить, является ли строка допустимым Mongo ObjectId, - использовать модуль mongodb .
const ObjectID = require('mongodb').ObjectID; if(ObjectID.isValid(777777777777777)){ console.log("Valid ObjectID") }
источник
Ниже представлена функция, которая проверяет с помощью
isValid
метода ObjectId иnew ObjectId(id)
возвращает ли одно и то же значение. Причина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; }
источник
Если у вас есть шестнадцатеричная строка, вы можете использовать это:
ObjectId.isValid(ObjectId.createFromHexString(hexId));
источник
Мне потребовалось некоторое время, чтобы получить действительное решение, поскольку предложенное @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 }
источник
Для мангуста используйте функцию 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'); }
источник
В ответе на решение Энди Маклауд сказал:
Реализацией этого подхода была бы функция, которая проверяет, является ли переданное значение допустимым
ObjectId
и работает со значениямиstring
иObjectId
(объекта). Это выглядело бы примерно так: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; }
источник
@ ross-u ответ просто потрясающий.
Я связал методы для полной встроенной проверки:
documentId = id && isValid(id) && new ObjectId(id) == id ? id : null
Обратите внимание на двойной знак равенства, который ОЧЕНЬ важен, поскольку
new ObjectId()
не возвращает строку, а строгое сравнение вернет false при сравнении с нормальной строкой (что я использовал в своей логике).Методы были деструктурированы из
mongoose
объекта, предоставленного требованием:const { Types: { ObjectId: { isValid }, ObjectId } } = require("mongoose");
источник
Предупреждение: isValid вернет true для строк произвольной длины 12/24, начинающихся с допустимой шестнадцатеричной цифры. В настоящее время я думаю, что это лучшая проверка:
источник
true
для'funky string'
. Ему подойдет любая строка подходящей длины, начинающаяся с шестнадцатеричной цифры.