【问题标题】:Calling lean() after findOneDocument vs lean() on returned document - Why is calling lean() on returned document not working?在 findOneDocument 与返回文档上的精益()之后调用精益() - 为什么在返回的文档上调用精益()不起作用?
【发布时间】:2021-04-04 00:52:30
【问题描述】:

这是我得到的错误 => "TypeError: apartment.lean is not a function"

在这段代码中,我收到一条错误消息,提示lean() 不是函数:

let apartment = await Apartment.findOne({
    'address.placeId':req.body.placeId,
    'address.apartmentNumber':req.body.apartmentNumber
});

if(apartment){
    //fetch references of pictures belonging to the apartment and send them back to the user
    const pictureReferences = fetchPictureReferences(apartment._id);
    let apartmentPoJo = apartment.lean();
    apartmentPoJo.pictures=[...pictureReferences];

    
    return res.status(200).json({msg:'Apartment Found',apartment:apartmentPoJo});
}

在该代码中,它运行良好,基本上是在 findOne() 完成后立即调用lea() 函数:

let apartment = await Apartment.findOne({
    'address.placeId':req.body.placeId,
    'address.apartmentNumber':req.body.apartmentNumber
}).lean();

if(apartment){
    //fetch references of pictures belonging to the apartment and send them back to the user
    const pictureReferences = fetchPictureReferences(apartment._id);
    apartment.pictures=[...pictureReferences];

    
    return res.status(200).json({msg:'Apartment Found',apartment});
}

你能告诉我为什么它们不同吗?我假设 findOne() 函数返回一个文档。是当场执行还是在我创建的新变量上执行?

感谢您的澄清!

【问题讨论】:

    标签: reactjs mongodb mongoose


    【解决方案1】:

    简而言之,lean 只是Model(或Query)类的一个方法。返回的Document 类没有lean 方法。

    Models 和 Documents 都是 Mongoose 类,但它们并不相同。在 Model 上调用 Query 方法(如 findOne)会返回一个文档实例

    Document Methods

    Model Methods

    Query Methods(大部分these methodsModel类的一部分)

    const findApartment = async (req, res) => {
      try {
        const { apartmentNumber, placeId } = req.body;
        if (!apartmentNumber || !placeId) throw String("You must supply a valid apartment and id!"); 
      
        /* 
           Using the Apartment model, we invoke Query methods "findOne" and "lean".
           
           The result of these two queries is a document instance transformed into 
           a plain Javascript object (a plain object where Mongoose virtuals are removed) 
           
           If you ran the query without invoking "lean", then "findOne" 
           would return an instance of a Document, which contain the methods
           associated with Documents -- as shown above, the Document class does not 
           contain the "lean" method.
        */
        const apartment = await Apartment.findOne({
          'address.placeId': placeId,
          'address.apartmentNumber': apartmentNumber
        }).lean();
        if (!apartment) throw String("Unable to locate the apartment with that address!");
    
        return res.status(200).json({msg: 'Apartment Found', apartment });
      } catch (err) {
        return res.status(404).json({ msg: err.toString() });
      }
    };
    
    

    令人困惑的部分可能是模型和文档可能共享相同的方法名称(例如填充:DM),但它们并不相同。

    更多关于精益的信息可以在here找到。

    【讨论】:

    • 谢谢,很清楚!让我再次想知道如何在 javascript 中调用方法。我一直认为,我们依次调用的方法,其实是上一个调用的方法返回对象的属性。以 a.b().c() 为例,'a' 调用方法 b,它是 a 的属性。然后调用方法c,这是b返回的对象的一个​​属性。在这种情况下,a.b().c() 实际上是“a”调用方法 b,它是 a 的属性,然后调用方法 c,它也是 a 的属性。
    • Mongoose 最有可能使用prototype chaining,其中:ba 的方法,cb 的方法,d 是@987654342 的方法@ 等等。这样,您可以(几乎)以任何顺序组合方法:Model.findOne().populate().select()Model.findOne().select().populate() 等等。如果您真的有兴趣,那么我建议您深入了解Mongoose source
    • 是的,我只是稍微深入一点,似乎它有点像一个中间件函数,其中新方法改变了“查询”对象的原型,然后将其传递。在这种情况下,每个方法都在更改 Query 原型并返回 Query 对象以供下一个函数继续更改 Query。最终执行这个 Query 的是 .exec 函数,它返回一个可用的 promise。它在我编写的代码中不太明显,这使它令人困惑,因为我没有显示 .exec() 调用。 >> mongoosejs.com/docs/…?
    猜你喜欢
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 2016-09-27
    • 2018-02-11
    • 2011-07-06
    相关资源
    最近更新 更多