क्या मैं यह निर्धारित कर सकता हूं कि क्या स्ट्रिंग एक MongoDB ऑब्जेक्ट है?


81

मैं एक स्ट्रिंग को BSON में परिवर्तित करके MongoDB लुकअप कर रहा हूं। क्या मेरे लिए यह निर्धारित करने का कोई तरीका है कि मेरे पास जो स्ट्रिंग है वह रूपांतरण करने से पहले मानगो के लिए एक वैध ऑब्जेक्ट है?

यहाँ मेरे वर्तमान findByID फ़ंक्शन के लिए कॉफ़ीस्क्रिप्ट है। यह बहुत अच्छा काम करता है, लेकिन मैं एक अलग विशेषता द्वारा देखना चाहता हूं यदि मैं यह निर्धारित करता हूं कि स्ट्रिंग एक आईडी नहीं है।

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

अभी के लिए, एक कोशिश पकड़ने ब्लॉक काम करता है का उपयोग कर। क्या यह अनुशंसित उपाय है?
होगा

जवाबों:


145

मैंने पाया कि मानगो ऑब्जेक्टआईड मान्यकर्ता वैध ऑब्जेक्ट्स को मान्य करने के लिए काम करता है, लेकिन मुझे कुछ मामले ऐसे मिले जहां अमान्य आईडी को वैध माना गया था। (उदाहरण: कोई भी १२ अक्षर लंबा तार)

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

जो मेरे लिए काम कर रहा है वह एक ऑब्जेक्ट ऑब्जेक्ट को स्ट्रिंग कर रहा है और फिर जाँच रहा है कि मूल स्ट्रिंग ऑब्जेक्टआईड के स्ट्रिंग मान से मेल खाता है।

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

यह कार्य क्योंकि मान्य आईडी किसी ऑब्जेक्टआईड में डाले जाने पर परिवर्तित नहीं होता है, लेकिन एक ऑब्जेक्ट जो एक मान्य मान्य हो जाता है, उसे ऑब्जेक्टआईड में डालने पर बदल जाएगा।


सैद्धांतिक रूप से आप इन दोनों तरीकों को जोड़ सकते हैं एक बहुत ही अच्छे ऑब्जेक्ट ऑब्जेक्ट सत्यापनकर्ता को उत्पन्न करने के लिए, जो आज किया जाएगा।
एंथनी

2
तो, इस तरह से कुछ? function checkObjectIdValid(id){ if(ObjectID.isValid(id)){ if(new ObjectID(id) === id){ return true } else { return false } } else { return false } }
जैक्सन वॉन

ऐसा कुछ काम करेगा, या स्ट्रिंग की तुलना ObjetcId के इनस्ट्रिंग फ़ंक्शन का उपयोग करके करेगा।
एंडी मैकलोड

2
दरअसल @JacksonVaughan का जवाब लगभग सही है। नई स्ट्रिंग (आईडी) को स्ट्रिंग में बदलने के लिए एक स्ट्रिंग () को याद कर रहा था क्योंकि हम इसे दूसरे स्ट्रिंग से तुलना कर रहे हैं। यहाँ पूर्ण सही उत्तर है: 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 } }
marcvander

1
@marcvander मुझे es6ify है कि तुम्हारे लिए:isObjectIdValid = id => ObjectId.isValid(id) ? String(new ObjectId(id) === id) ? true : false : false;
Rod911

82

आप उसके लिए परीक्षण करने के लिए एक नियमित अभिव्यक्ति का उपयोग कर सकते हैं:

कॉफ़ी

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

जावास्क्रिप्ट

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

1
हम्म यह गैर-वस्तु के रूप में अच्छी तरह से मेल खा सकता है, सबसे अच्छा तरीका या तो कल्पना के आधार पर एक सत्यापनकर्ता का निर्माण करना है और इसके विशिष्ट भागों को regex करना या एक नया ऑब्जेक्ट बनाने और पकड़ने के लिए एक पकड़ ब्लॉक बनाने की कोशिश करना है अगर यह कर सकता है।
सम्मे

2
@Sammaye यह वही मान्यता है जो BSON ObjectID कंस्ट्रक्टर द्वारा उपयोग की जाती है । क्या आप मुझे एक गैर-ऑब्जेक्ट स्ट्रिंग का उदाहरण दे सकते हैं जो यह मेल खाएगा?
जॉनीएचके

वाह, मैंने नहीं देखा कि आ रहा है। वैसे कोई भी 24 वर्ण का तार जिसमें संख्याएँ और अक्षर होते हैं, जैसेlol456712bbfghLLsdfr
सम्मे

13
@Sammaye लेकिन यह एक मान्य ऑब्जेक्ट है, इसलिए इसे मेल खाना चाहिए।
जॉनीएचके

1
शायद सही तरीका है, आधिकारिक तौर पर mongoose github.com/Automattic/mongoose/issues/…
आदर्श सतीजा

10

मैंने अतीत में ऐसा करने के लिए देशी नोड मोंगोडब ड्राइवर का उपयोग किया है। TheValid विधि यह जाँचती है कि मान एक वैध BSON ObjectId है। यहां प्रलेखन देखें।

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

एक यादृच्छिक संख्या के लिए सही रिटर्न ऊपर काम करने के लिए प्रतीत नहीं होता है।
डैन ओचियाना

1
मुझे लगता है कि यह सबसे अधिक संभावना है क्योंकि यह होना चाहिए ObjectId, नहीं ObjectID। :)
केन हॉफ

इसका उत्तर स्वीकार किया जाना चाहिए, मोंगोज़ की कोई आवश्यकता नहीं
FH

5

यदि आप Mongoose का उपयोग कर रहे हैं, तो हम यह परीक्षण कर सकते हैं कि क्या स्ट्रिंग 12 बाइट्स की है या 24 -x वर्णों के स्ट्रिंग को mongoose build-in -ValidObjectId का उपयोग करके ।

mongoose.isValidObjectId (स्ट्रिंग) सही / गलत लौटेगा

यह स्वीकृत समाधान द्वारा प्रदान किया गया एक उन्नत समाधान है


गंभीरता से, चलो इस बात को वोट दें। पुराने स्वीकृत जवाब बहुत अच्छा था जब पुस्तकालय ने इसके लिए कोई समर्थन नहीं दिया, लेकिन अब यह करता है। बाईपास करने के लिए यह एक हैक है जो कार्यान्वयन विवरण पर निर्भर करता है।
lance.dolan

4

यहाँ कुछ कोड मैंने @ andy-macleod के उत्तर के आधार पर लिखे हैं।

यह या तो एक int या string या ObjectId ले सकता है और एक वैध ObjectId लौटाता है यदि पारित मूल्य वैध या शून्य है यदि अमान्य है:

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

mongoose.Types.ObjectId.isValid (स्ट्रिंग) हमेशा सही होता है यदि स्ट्रिंग में 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

2

एकमात्र तरीका जो मुझे मिला है वह है कि मैं जिस मूल्य की जांच करना चाहता हूं, उसके साथ एक नया ऑब्जेक्ट बनाएं, यदि इनपुट आउटपुट के बराबर है, तो आईडी मान्य है:

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

1

सबसे आसान तरीका मूल रूप से एक कोशिश और कैच सेवा में अपना ऑब्जेक्टआईड तरीका है। तब आप इस विधि का उपयोग सीधे विधि का उपयोग करने के बजाय, ओब्जेसेट आईडी को संभालने के लिए कर रहे हैं:

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
}

एक नई जनरेट आईडी प्राप्त करने के लिए आप अशक्त या खाली प्रॉप्स भी भेज सकते हैं।


1

यह जांचने का सबसे सरल तरीका है कि क्या स्ट्रिंग एक वैध मानगो ऑब्जेक्टआईड है जो मोंगोडब मॉड्यूल का उपयोग कर रहा है।

const ObjectID = require('mongodb').ObjectID;

if(ObjectID.isValid(777777777777777)){
   console.log("Valid ObjectID")
}

1

नीचे एक फ़ंक्शन है जो ऑब्जेक्ट ऑब्जेक्ट isValidविधि के साथ दोनों की जांच करता है और 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;
}

समीक्षा के लिए धन्यवाद। मैंने वर्णन को अद्यतन किया
अलीअवसी

2
यह काम नहीं करेगा क्योंकि आप स्ट्रिंग और ऑब्जेक्ट आईडी के बीच एक सख्त तुलना कर रहे हैं। कृपया डबल बराबर करने के लिए अद्यतन करें।
मटिया रसूलो

0

यदि आपके पास हेक्स स्ट्रिंग है तो आप इसका उपयोग कर सकते हैं:

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

0

एक वैध समाधान प्राप्त करने में मुझे कुछ समय लगा क्योंकि @Indy Macleod द्वारा प्रस्तावित ऑब्जेक्ट की अपनी स्वयं की स्ट्रिंग के साथ तुलना करने के लिए एक्सप्रेस.जेड सर्वर पर दुर्घटनाग्रस्त हो रहा था:

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
}

0

Mongoose के लिए, ObjectId वैध है या नहीं, यह जांचने के लिए UseValid () फ़ंक्शन का उपयोग करें

उदाहरण :

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

0

में समाधान जवाब एंडी Macleod ने कहा:

जो मेरे लिए काम कर रहा है वह एक ऑब्जेक्ट ऑब्जेक्ट को स्ट्रिंग कर रहा है और फिर जाँच रहा है कि मूल स्ट्रिंग ऑब्जेक्टआईड के स्ट्रिंग मान से मेल खाता है।

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

यह कार्य क्योंकि मान्य आईडी किसी ऑब्जेक्टआईड में डाले जाने पर परिवर्तित नहीं होता है, लेकिन एक ऑब्जेक्ट जो एक मान्य मान्य हो जाता है, उसे ऑब्जेक्टआईड में डालने पर बदल जाएगा।

इस दृष्टिकोण के एक कार्यान्वयन, एक समारोह है कि अगर जांच में सफल हो गया मान एक मान्य है होगा 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;
}

0

@ रोस-यू जवाब सिर्फ अद्भुत है।

मैंने पूर्ण सत्यापन इनलाइन करने के लिए विधियों की जंजीर बनाई है:

documentId = id && isValid(id) && new ObjectId(id) == id ? id : null

डबल समान चिह्न पर ध्यान दें, जो बहुत महत्वपूर्ण है new ObjectId() एक स्ट्रिंग वापस नहीं करता है और एक सामान्य स्ट्रिंग (जो मैं अपने तर्क में आ रहा था) की तुलना में सख्त तुलना झूठी हो जाएगी।

mongooseआवश्यकता से उजागर वस्तु से विधियां नष्ट हो गई हैं:

const {
  Types: {
    ObjectId: { isValid },
    ObjectId
  }
} = require("mongoose");

-2

चेतावनी: अगर है वापस आ जाएगी सच मनमाना 12/24 लंबाई मान्य हेक्स अंकों के साथ शुरुआत स्ट्रिंग्स के लिए। वर्तमान में मुझे लगता है कि यह एक बेहतर जाँच है:

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


3
यह करने के लिए मूल्यांकन करेगा trueके लिए 'funky string'। कोई भी स्ट्रिंग जो सही लंबाई है और एक हेक्स अंक से शुरू होती है, उसे संतुष्ट करेगी।
जॉनीएचके
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.