📅  最后修改于: 2023-12-03 15:19:39.267000             🧑  作者: Mango
在使用Mongoose操作MongoDB时,默认情况下,查询结果是Mongoose Document对象。它们包含了一些Mongoose的方法和属性,比如save()、validate()、_id等。但是,Document对象通常会占用更多的内存,并且在大多数情况下,并不需要这些额外的方法和属性。因此,Mongoose提供了一种方法让你的查询结果可以轻松地以纯JavaScript对象的形式返回,这就是Query.prototype.lean()方法。
当你在查询操作中调用lean()方法后,将会以纯JavaScript对象的形式返回查询结果,而不会返回Mongoose Document对象。这个方法是在Model.prototype.find()和Query.prototype.exec()方法之前调用的,如下面的例子所示:
const mongoose = require('mongoose');
const User = mongoose.model('User');
// 返回一个Promise
const usersPromise = User.find({ age: { $gte: 18 } }).lean().exec();
usersPromise.then(function(users) {
// users 是一个js对象,而不是Mongoose Document对象
});
查询结果以JavaScript对象形式返回是有很多好处的,首先是性能方面的提升。当你以Mongoose的文档形式返回查询结果时,Mongoose会执行很多的中间件和钩子函数。这些多余的操作将会占用更多的内存,导致查询速度变慢。通过lean()方法,你可以更快地获取到查询结果。
另一个好处是灵活性。当你以JavaScript对象形式返回查询结果时,你可以自由地转换格式、自定义任何属性和方法。比如,当你想获取一个用户列表时,直接使用lean()方法可以更快地得到结果,并且你可以在返回的用户对象中自由地添加任何属性和方法。
const usersPromise = User.find().lean().exec();
usersPromise.then(function(users) {
// 使用map()方法自定义属性和方法
const formattedUsers = users.map(function(user) {
return {
id: user._id.toString(),
name: user.name,
email: user.email,
isAdmin: (user.role === 'admin'),
fullName: user.firstName + ' ' + user.lastName,
uppercaseName: function() {
return this.name.toUpperCase();
}
};
});
// 对结果进行排序
const sortedUsers = formattedUsers.sort(function(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
});
// 返回结果
res.json(sortedUsers);
});
在使用lean()方法时,需要注意几个问题。首先,要注意对象的类型,因为lean()方法返回的是一个普通的JavaScript对象,而不是一个Mongoose Document对象。因此,这个对象没有Mongoose的方法和属性,比如save()、validate()、_id等,无法直接使用Mongoose的实例方法。如果需要使用这些方法,需要在使用之前将对象转成Mongoose Document对象。
另一个需要注意的事项是,当一个查询结果以lean()方法返回时,它不会修改原始的Mongoose Document对象。如果想要修改数据,必须执行数据存储操作,比如Model.prototype.update()、Model.prototype.findOneAndUpdate()等。
最后,使用lean()方法返回的数据可能会出现误差。这是因为MongoDB在内部处理数据时会执行很多优化操作,而这些操作可能会影响查询结果。如果需要完全准确的数据,最好还是采用Mongoose的文档形式获取查询结果。
Query.prototype.lean()方法是Mongoose提供的一种快速获取纯JavaScript对象的方法。这个方法在性能和灵活性方面都有很大的优势,但也需要注意返回的对象类型和误差问题。使用时需要根据具体的情况进行权衡和选择。