📌  相关文章
📜  Query.prototype.lean() 如何在Mongoose中工作?(1)

📅  最后修改于: 2023-12-03 15:19:39.267000             🧑  作者: Mango

Mongoose中的Query.prototype.lean()介绍

在使用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对象的方法。这个方法在性能和灵活性方面都有很大的优势,但也需要注意返回的对象类型和误差问题。使用时需要根据具体的情况进行权衡和选择。