2015-03-12 9 views
8

मैं मोंगोज़ का उपयोग बहुत बड़े मोंगो डेटाबेस के साथ कर रहा हूं, और मुझे 10 सेकंड के बाद MySet.find({}) जैसे महंगा प्रश्न चाहिए।मैं मोंगोस क्वेरी पर टाइमआउट कैसे सेट करूं?

मैं अपने कनेक्शन पर एक सॉकेट समाप्ति सेट करने की कोशिश की है, लेकिन सर्वर क्रैश हो जाता है अगर समय समाप्ति को पार कर जाता है:

var options = {server: {socketOptions: {socketTimeoutMS: 10000}}}; 
var conn = mongoose.connect('mongodb://localhost/my_db', options); 

मैं find कार्य करने के लिए maxTimeMS विकल्प गुजर की कोशिश की है, लेकिन वह 'नहीं करता है टी पर कोई प्रभाव नहीं है:

MySet.find({}, {}, {timeout: true, maxTimeMS: 10000}, function(err, doc) {}); 

कोई विचार?

+0

आप MongoDB 2.6 या उच्चतर का उपयोग कर रहे के बाद से मोंगो शैल में पदावनत कर रहा है? –

+0

'मोंगो - वर्जन' कहते हैं 'मोंगोडीबी शैल संस्करण: 2.6.8'। –

+0

ऐसा लगता है कि 'maxTimeMS' विकल्प के लिए Mongoose समर्थन [3.8.13 में जोड़ा गया था] (https://github.com/learnboost/mongoose/blob/master/History.md#3813--2014-07-15)। आपका मोंगोस संस्करण क्या है? – JohnnyHK

उत्तर

-1

मुझे लगता है कि यह काम करना चाहिए।

db.mycoll.find()। MaxTimeMS (50)

+0

वह मूल मोंगोडीबी चालक के लिए काम करेगा, लेकिन यह मोंगोस के लिए काम नहीं करता है। –

-7

मैं अंत में यह काम कर रहा मिला है। सबसे पहले मैं बाहर जब सॉकेट (यानी एक प्रश्न) बार दुर्घटनाग्रस्त से सर्वर को रोकने:

//don't crash the server if a query times out 
mongoose.connection.on('error', function() {}); 

फिर, हर बार जब मैं डेटाबेस क्वेरी, मैं से डिस्कनेक्ट करने और डेटाबेस से पुन: कनेक्ट, 10000 socketTimeoutMS की स्थापना करना चाहते हैं:

mongoose.disconnect(); 
mongoose.connect('mongodb://localhost/my_db', { 
    server: {socketOptions: {socketTimeoutMS: 10000}} 
}); 
MySet.find({}, function(err, doc) {}); 

यह ठीक से 10 सेकंड निष्पादन के बाद क्वेरी को काट देता है।

+0

प्रत्येक क्वेरी पर डिस्कनेक्ट/रीकनेक्ट महंगा होगा? – avmohan

+3

प्रत्येक क्वेरी पर दोबारा जुड़कर आप जिस ओवरहेड का भुगतान कर रहे हैं, वह इस दृष्टिकोण को सब कुछ के लिए उपयोग करने योग्य बनाता है लेकिन सबसे सरल ऐप्स। –

6

आप इसे Query#maxTime विधि से कर सकते हैं जो मोंगोस में स्वयं दस्तावेज़ नहीं है, लेकिन mquery लाइब्रेरी का हिस्सा है जो मोंगोस अपने धाराप्रवाह क्वेरी इंटरफ़ेस के लिए उपयोग करता है।

तो आपके मामले में, आप इसे के रूप में कहेंगे:

MySet.find({}).maxTime(10000).exec(function(err, doc) { ... }); 

आप इसे सही ढंग से mongoose.set('debug', true); के माध्यम से नेवला डिबगिंग को सक्षम करने से maxTimeMS विकल्प सेट करते हैं पुष्टि कर सकते हैं और फिर आप इस क्वेरी कि लग रहा है के लिए कंसोल आउटपुट देखेंगे जैसे:

Mongoose: myset.find({}) { maxTimeMS: 10000, safe: true, fields: {} } 
+0

क्या आप जानते हैं कि यह 'populate()' पर भी किया जा सकता है? यहां की तरह: http://stackoverflow.com/questions/42398696/mongoose-model-populate-query-timeout – Zlatko

+0

क्या इस क्वेरी को वैश्विक रूप से सभी क्वेरी में जोड़ने का कोई विकल्प है? –

-1

यह वह पैटर्न है जिसे मैंने बहुत उपयोग करना शुरू कर दिया है।

// Default time out timeout in ms 
const DEFAULT_TIME_OUT = 500; 

// Default timeout message 
const DEFAULT_MESSAGE = `Timeout fetching data(${DEFAULT_TIME_OUT}ms)`; 

// Function that triggers a Promise's reject after a set amount of time 
function timeoutReject(reject, message, timeout) { 
    setTimeout(function(){ 

    // Reject the Promise if the time is reached 
    reject(message || DEFAULT_MESSAGE); 
    }, timeout || DEFAULT_TIME_OUT); 
}; 

function youAreNotAuthentic() { 
    // Logic to validate user and request return boolean 
}; 

// Throw error if the user cannot access this data 
function youCantTouchThis() { 
    throw new Error('You cannot access this data.'); 
}; 

// Function to request data 
function getDataById(_id) { 
    // First check if this is authentic 
    if (youAreNotAuthentic()) youCantTouchThis(); 

    // Return a Promise 
    return new Promise((resolve, reject) => { 

    // Set a timeout to reject if we do not get a response in x time 
    timeoutReject(reject, 'Custom Message', 300); 

    // Could look like this to just use the defaults 
    // timeoutReject(reject); 

    // Query for the data 
    Collection.findOne({ _id }).then(data => { 

     // Resolve the Promise with the retrieved data 
     resolve(data); 
    }); 
    }); 
}; 

इस तरह से मैं सबसे अनुरोध करने के लिए लागू एक डिफ़ॉल्ट टाइमआउट है लेकिन फिर मैं यह कर सकते हैं अगर मैं एक प्रति कॉल के आधार पर समायोजित करने की आवश्यकता। या मुझे उन क्षेत्रों के बारे में जानकारी दी जा सकती है जिन्हें बेहतर अनुक्रमण की आवश्यकता है।

+0

कुछ ने सामान्य उद्धरण के लिए "एकल कोण वाला उद्धरण" सुझाया और अनुमोदित किया है। यह काम नहीं करेगा। यह एक टेम्पलेट स्ट्रिंग होने के लिए है। 'सही नहीं है ''। – bcbrian

0

टी एल; डॉ:

MySet.find({ $query: { /*Query here*/ }, $maxTimeMS: 10000 }); 

आपने इस क्वेरी के साथ परीक्षण कर सकते हैं:

MySet.find({ $query: {"$where": "sleep(100) || true"}, $maxTimeMS: 10000 }); 

यह क्यों काम करता है:

आप उपयोग कर सकते हैं Query modifiers

और especialy इस एक: $maxTimeMS

सावधान रहें: इस ऑपरेटर v3.2

संबंधित मुद्दे