Mongoose排序后无法获取普通JavaScript对象问题求助
解决Mongoose中使用sort()同时获取普通JavaScript对象的问题
嘿,我完全懂你碰到的这个坑——明明加了.lean(),可一用上.sort()就还是返回Mongoose文档对象,去掉sort就正常了对吧?别着急,咱们来捋清楚问题出在哪,以及怎么解决:
核心思路:确保.lean()的调用逻辑正确
Mongoose的.lean()是用来告诉框架直接返回普通JS对象而非文档实例的修饰符,只要调用时机正确,搭配.sort()完全没问题。下面给你几个稳妥的解决方案:
方案1:调整链式调用顺序(避版本兼容坑)
虽然按Mongoose的设计,.lean()的位置不影响功能,但把它放在.sort()之后、.exec()之前,有时候能避开旧版本的小bug,试试这个写法:
chatModel.find({'userId': userId}, { "_id": 0, "message": 1, "type": 1 }) .sort({ createdDateISO: -1 }) .lean() // 关键:在exec执行前调用lean .exec((err, result) => { if (err) { console.error(err); return; } // 验证是否为普通对象: console.log(typeof result[0]); // 输出 "object" console.log(result[0] instanceof mongoose.Document); // 输出 false });
方案2:把sort规则放到find的配置参数里
如果你还是碰到问题,可以换一种方式指定排序——把sort作为find()的第三个配置参数传入,不用链式调用.sort():
chatModel.find( {'userId': userId}, { "_id": 0, "message": 1, "type": 1 }, { sort: { createdDateISO: -1 } } // 将sort配置在这里 ) .lean() .exec((err, result) => { // 这里拿到的就是纯JS对象数组 });
方案3:改用async/await写法(更直观不易错)
如果项目支持ES6+异步语法,用async/await能让代码逻辑更清晰,也减少链式调用的顺序问题:
async function getUserChats(userId) { try { const chatList = await chatModel.find( {'userId': userId}, { "_id": 0, "message": 1, "type": 1 } ) .sort({ createdDateISO: -1 }) .lean(); return chatList; // 返回纯JS对象数组 } catch (err) { console.error(err); throw err; } } // 调用示例 getUserChats(yourUserId).then(chats => { console.log(chats); });
额外检查建议
- 升级Mongoose版本:如果用的是4.x及更早的版本,建议升级到5.x以上,旧版本可能存在
.lean()和.sort()的兼容bug - 验证返回结果:普通JS对象不会有
__v、save()这类Mongoose文档特有的属性和方法,打印出来一看便知
内容的提问来源于stack exchange,提问作者shamon shamsudeen
相关产品推荐
相关产品推荐

