web-dev-qa-db-fra.com

Puis-je déterminer si une chaîne est un ObjectID MongoDB?

Je fais des recherches MongoDB en convertissant une chaîne en BSON. Est-il possible pour moi de déterminer si la chaîne que j'ai est un ObjectID valide pour Mongo avant d'effectuer la conversion?

Voici le coffeescript de ma fonction findByID actuelle. Cela fonctionne très bien, mais j'aimerais rechercher un attribut différent si je détermine que la chaîne n'est pas un identifiant.

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

J'ai trouvé que le validateur ObjectId Mongoose fonctionne pour valider des objectIds valides, mais j'ai trouvé quelques cas où des identifiants non valides étaient considérés comme valides. (par exemple: n'importe quelle chaîne de 12 caractères)

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

Ce qui a fonctionné pour moi est de convertir une chaîne en objectId, puis de vérifier que la chaîne d'origine correspond à la valeur de chaîne de objectId.

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

Cela fonctionne car les identifiants valides ne changent pas lorsqu'ils sont convertis en un ObjectId, mais une chaîne qui obtient une valeur false valide changera lorsqu'elle sera convertie en un objectId.

72
Andy Macleod

Vous pouvez utiliser une expression régulière pour tester cela:

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    
}
63
JohnnyHK

J'ai utilisé le pilote de noeud natif mongodb pour le faire dans le passé. La méthode isValid vérifie que la valeur est un ObjectId BSON valide. Voir la documentation ici.

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

Voici un code que j'ai écrit à partir de la réponse de @ andy-macleod.

Il peut prendre un int ou une chaîne ou ObjectId et renvoie un ObjectId valide si la valeur transmise est valide ou null si elle n'est pas valide:

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

mongoose.Types.ObjectId.isValid (chaîne) renvoie toujours True si la chaîne contient 12 lettres. 

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
0
Sajag Porwal

Pour mongoose, utilisez la fonction isValid () pour vérifier si objectId est valide ou non. 

Exemple :

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

Il m'a fallu un certain temps pour trouver une solution valable, car celle proposée par @Andy Macleod, qui consistait à comparer la valeur objectId avec sa propre chaîne, bloquait le serveur Express.js sur: 

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

Je viens d'utiliser un simple essai d'essayer de résoudre ce problème.

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
}
0
0112358

Si vous avez la chaîne hexagonale, vous pouvez utiliser ceci:

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

Le seul moyen que j'ai trouvé est de créer un nouvel ObjectId avec la valeur que je veux vérifier. Si l'entrée est égale à la sortie, l'identifiant est valide:

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
0
Daphoque

Le moyen le plus simple consiste à envelopper votre méthode ObjectId dans un service try and catch. Ensuite, vous utilisez ce service pour gérer les identifiants d'Objecet, au lieu d'utiliser directement la méthode:

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
}

Vous pouvez également envoyer des accessoires nuls ou vides pour obtenir un nouvel identifiant généré.

0
Raz