2012-12-13 10 views
40

Sto facendo ricerche MongoDB convertendo una stringa in BSON. C'è un modo per me per determinare se la stringa che ho è un ObjectID valido per Mongo prima di fare la conversione?Posso determinare se una stringa è un ObjectID MongoDB?

Ecco il coffeescript per la mia funzione findByID corrente. Funziona alla grande, ma mi piacerebbe cercare un attributo diverso se determino che la stringa non è un ID.

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

Per ora, con una prova di cattura opere di blocco. Questa è la soluzione consigliata? – Will

risposta

42

ho scoperto che il validatore mangusta ObjectId lavora per convalidare objectIds valido, ma ho trovato un paio di casi in cui gli ID non validi sono stati considerati validi. (Ad esempio: qualsiasi stringa lunga 12 caratteri)

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

Ciò che ha lavorato per me è colata una stringa in un objectId e poi controllando che la stringa originale corrisponde al valore di stringa del objectId.

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

questo lavoro perché ID validi non cambiano quando fusa a un ObjectId ma una stringa che ottiene una falsa valida cambierà quando pressofuso ad un objectId.

+0

Bella, la migliore risposta trovata finora su SO. – Antoine

+0

In teoria si potrebbero aggiungere questi due metodi per generare un validatore ObjectID maledettamente buono, lo otterremo oggi. – Antoine

56

È possibile utilizzare un'espressione regolare per verificare che:

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

Hmm questo potrebbe uguagliare anche i non oggetti, il modo migliore è creare un validatore basato sulle specifiche e regexare le parti specifiche o provare a creare un nuovo objectid e contenere un blocco catch da catturare se può farlo. – Sammaye

+2

@Sammaye È la stessa convalida utilizzata dal [costruttore ObjectID BSON] (https://github.com/mongodb/js-bson/blob/master/lib/bson/objectid.js#L15). Puoi darmi un esempio di una stringa non ObjectID che potrebbe corrispondere? – JohnnyHK

+0

Wow, non l'ho visto arrivare. Bene ogni stringa di 24 caratteri che contiene numeri e lettere, ad esempio 'lol456712bbfghLLsdfr' – Sammaye

5

ho usato il driver del nodo MongoDB nativo di fare questo in il passato. Il metodo isValid verifica che il valore sia un ObjectId BSON valido. See the documentation here.

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

non sembra funzionare, sopra restituisce true per un numero casuale. –

-1

Attenzione: isValid tornerà vero per arbitrari 12/24 stringhe di lunghezza che iniziano con una cifra esadecimale valido. Attualmente credo che questo sia un controllo migliore:

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

+1

Ciò valuterà a 'true' per' 'funky string''. Qualsiasi stringa che abbia la lunghezza giusta e inizi con una cifra esadecimale la soddisfi. – JohnnyHK

1

Ecco un codice che ho scritto in base alla risposta di @ andy-macleod.

Si può prendere sia un int o una stringa o ObjectId e restituisce un'ObjectId valida se il valore passato è valido o nullo se non è valido:

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

Se avete la stringa esadecimale è possibile utilizzare questo:

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

ci ho messo un po 'per ottenere una valida soluzione come quella proposta da @Andy Macleod del confronto tra il valore objectId con la propria stringa stava crollando il server Express.js on:

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

Ho appena usato un semplice try catch per risolvere questo problema.

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

Per mangusta, la funzione Usa isValid() per verificare se objectId è valido o meno

Esempio:

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