跳到主要内容

2 篇博文 含有标签「mongoose」

查看所有标签

_id 为 String 类型时出现 Mongoose Cast to ObjectId failed 解决方案

· 阅读需 2 分钟
{
"_id" : "Football",
"ancestors" : [
"Categories",
"Sports and fitness"
],
"parent" : "Sports and fitness"
}

模型定义如下

var mongoose = require('mongoose');

var Category = mongoose.Schema({
_id: String
});

var categorySchema = mongoose.Schema({
ancestors: [Category],
parent: [Category]
});


// Initiate database connection
var db = mongoose.createConnection('mongodb://localhost/Categories');
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
console.log("openDB categories");
});

module.exports.category = db.model('Category', categorySchema);
var categoryModel = require('../models/Category');
var Category = categoryModel.category;

exports.getAncestors = function(req, res) {
if (req.params.id == undefined){res.send("no id specified!"); return;}

Category.findOne({_id: 'Football'}, 'ancestors', function(err, ancestors){
if(err) console.log(err);

res.send(ancestors);
});
}

运行时发生错误

{ message: 'Cast to ObjectId failed for value "Football" at path "_id"',
name: 'CastError',
type: 'ObjectId',
value: 'Football',
path: '_id' }

解决方案

mongoose 默认将 _id 设为 ObjectId 类型。

var categorySchema = mongoose.Schema({
_id: String,
ancestors: [{type: String }],
parent: {type: String}
},{ _id: false });

var Category = mongoose.model( "Category", categorySchema );

mongoose 连接超时参数

· 阅读需 3 分钟

最近在项目中经常发生登录卡死的状况,由于是使用的 passport 单点登录,所以只能一步步排查,加日志。

最后发现是卡在一个 mongodb 查询那里,后来去官网查询后,发现查询超时时间默认是无限大的,所以导致我们看到的现象是 http 无返回,导致 http 超时了 , 因此 nginx 报 502 错误。

找到了 mongoose 文件的Connection部分,在下面可以看到有一些连接参数,其中就有 socketTimeoutMS 和 connectTimeoutMS,点击进入 mongodb 官方文档,可以看到Server 的参数中,socketTimeoutMS 默认是无限大的,这在连接外网 mongodb 时可能导致一些问题,我们需要加上超时参数。

var options = {
server: {
socketOptions: {
autoReconnect: true,
connectTimeoutMS: 10000,
socketTimeoutMS: 10000,
},
},
}

// Good way to make sure mongoose never stops trying to reconnect
mongoose.connect(uri, options);

有待观察后补充


尝试后发现,这个 socketTimeoutsocket 变成时的设置 timeout 是一个效果,闲置超时时间,但是在 linux 下似乎没有什么不正常,在 windwos 上就是启动后,过了这个时间就会抛出一个 timeout 错误。