web-dev-qa-db-ja.com

文字列がMongoDB ObjectIDかどうかを判断できますか?

文字列をBSONに変換してMongoDBルックアップを行っています。変換を行う前に、持っている文字列がMongoの有効なObjectIDであるかどうかを判断する方法はありますか?

以下は、現在のfindByID関​​数のコーヒースクリプトです。うまくいきますが、文字列がIDではないと判断した場合は、別の属性で検索したいと思います。

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

Mongoose ObjectIdバリデーターは有効なobjectIdを検証するために機能することがわかりましたが、無効な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にキャストされると変化するためです。

89
Andy Macleod

正規表現を使用して、それをテストできます。

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

過去にネイティブノードmongodbドライバーを使用してこれを実行しました。 isValidメソッドは、値が有効なBSON ObjectIdであることを確認します。 こちらのドキュメントをご覧ください

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

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

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

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');
}
0
Om Sharma

ObjectId値と独自の文字列を比較する@Andy Macleodが提案したものが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
}
0
Vibhu

16進文字列がある場合、これを使用できます。

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

私が見つけた唯一の方法は、チェックしたい値で新しいObjectIdを作成することです。入力が出力と等しい場合、idは有効です:

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

最も簡単な方法は、基本的に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を取得することもできます。

0
Raz