我正在使用Mongoose和一个非常大的Mongo数据库,我希望像MySet.find({})
这样昂贵的查询在10秒后超时。
我已经尝试在我的连接上设置套接字超时,但是如果超时超时则服务器崩溃:
var options = {server: {socketOptions: {socketTimeoutMS: 10000}}};
var conn = mongoose.connect('mongodb://localhost/my_db', options);
我已尝试将maxTimeMS选项传递给find函数,但这根本没有任何效果:
MySet.find({}, {}, {timeout: true, maxTimeMS: 10000}, function(err, doc) {});
有什么想法吗?
答案 0 :(得分:9)
您可以使用Mongoose本身未记录的Query#maxTime
方法执行此操作,但它是Mongoose用于其流畅查询界面的mquery
库的一部分。
所以在你的情况下,你会把它称为:
MySet.find({}).maxTime(10000).exec(function(err, doc) { ... });
您可以通过maxTimeMS
启用Mongoose调试来确认它是否正确设置mongoose.set('debug', true);
选项,然后您将看到此查询的控制台输出,如下所示:
Mongoose: myset.find({}) { maxTimeMS: 10000, safe: true, fields: {} }
答案 1 :(得分:0)
MySet.find({ $query: { /*Query here*/ }, $maxTimeMS: 10000 });
您可以使用此查询进行测试:
MySet.find({ $query: {"$where": "sleep(100) || true"}, $maxTimeMS: 10000 });
您可以使用Query modifiers
特别是这一个:$maxTimeMS
小心:自v3.2起,mongo Shell中不推荐使用此运算符
答案 2 :(得分:-2)
我认为这应该有用。
db.mycoll.find()。maxTimeMS(50)
答案 3 :(得分:-2)
这是我开始大量使用的模式。
// 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);
});
});
};
这样我就会对大多数请求应用默认超时,但如果我需要根据每个呼叫进行调整,那么我可以。或者我可以了解需要更好索引的区域。
答案 4 :(得分:-8)
我终于开始工作了。首先,我阻止服务器在套接字(即查询)超时时崩溃:
//don't crash the server if a query times out
mongoose.connection.on('error', function() {});
然后,每次我想查询数据库时,我断开连接并重新连接到数据库,将socketTimeoutMS设置为10000:
mongoose.disconnect();
mongoose.connect('mongodb://localhost/my_db', {
server: {socketOptions: {socketTimeoutMS: 10000}}
});
MySet.find({}, function(err, doc) {});
这会在执行10秒后切断查询。