zoukankan      html  css  js  c++  java
  • 解决Mongoose 返回的文档过大导致模板引擎art-template无法渲染的问题,错误-RangeError: Maximum call stack size exceeded

    参考:https://blog.csdn.net/qq_40659195/article/details/88411838

    最近尝试用Node写一个小案例,使用到了MongoDB,使用过的人可以知道,Node-js操作MongoDB的官方包实在有些麻烦,为了方便开发,使用了mongoose这样的一个中间插件,但是却发现,查询的数据无法通过art-template渲染(注: 这里使用的express框架,通过express配置的art-template),结果报错:

    Maximum call stack size exceeded
    at Buffer.get [Symbol.toStringTag] ()
    at Buffer.toString ()

    根据问题描述,应该是内存问题,按照我的性格,当然先百度一下(有谷歌的通知勿喷,最近翻墙老是出问题),大多数写的都是递归造成的问题描述,我靠,这和我情况一毛钱关系没有,故转而还是自己想办法,经过一番折腾,发现,只有mongoose返回的文档对才会导致该问题,如果自己定义的JSON数据或者对象的数据都没有这样的情况,果断得出结果------是mongoose返回文档对象太过庞大造成,然后又折腾了一番,toString,对象拷贝,都没有成功,因为文档对象是不可变的(这句话现在是有些正确的,尽管还没有绝对的证据)!最后按照JSON格式数据操作一番,

    先通过JSON.stringify()这个方法将文档对象转为字符串,将他的其他属性全部格式掉,只需要留下需要的数据字符串即可!

    然后再通过JSON.parse()这个方法转为对象,这个方法虽然丢失效率,但是暂时解决问题,后面有更好的解决方案或者楼主得到了原因会更新解决方法和方案!代码附上,希望了解该问题的大神能提点一二!

    评论区解决方案引申:

    可以在查询链上使用lean()。告诉mongoose返回普通对象 不返回mongoose文档对象

    我的最终解决方案:

    // 解决方案1:
    // 使用lean()
    // let result = await Article.find({}).populate('author').lean();
    
    // 解决方案2:
    // 如果使用了第三方模块mongoose-sex-page控制查询数据,则不能使用lean()。
    // 导入第三方模块mongoose-sex-page控制分页查询的数据
    const pagination = require('mongoose-sex-page');
    let result = await pagination(Article).page(1).size(4).display(5).find({}).populate('author').exec();
    
    result = JSON.stringify(result);
    result = JSON.parse(result); 
    

    知识扩展:

    参考:Mongoose - lean
    Faster Mongoose Queries With Lean

    默认情况下,Mongoose查询返回Mongoose Document类的实例。 文档比普通的JavaScript对象重得多,因为它们具有很多用于跟踪更改的内部状态。 启用lean选项会告诉Mongoose跳过实例化完整的Mongoose文档,只给您POJO。

    lean属性的作用:跳过转换为MongooseDocuments类型,直接返回JS Object,从而便于我们修改查询结果。

    mongoose查询:

    • Model.findOne({});
    • Model.save();

    以上2种查询返回的数据实际上是Mo

    ngooseDocuments对象(mongoose自己封装的一个对象),并且这个对象会对数据进行实时查询以保证其符合预定义的model。所以添加其它model中没有的属性时是无法添加成功的。

    要想添加成功有2种方法:

    1. 查询时添加lean,
    • Model.findOne({}).lean();
    • Model.findOne({lean:true},function(err,result){});
    • Model.findOne({}).lean().exec(function(err,result){});
    1. 将查询结果转为object,查询结果result.toObject();
  • 相关阅读:
    八皇后问题
    窃贼问题
    汉诺塔算法
    HDOJ(HDU) 1570 A C
    HttpClient4.2 Fluent API学习
    CUDA编程(六)进一步并行
    动态规划-迷宫-百度之星-Labyrinth
    hdu 5288||2015多校联合第一场1001题
    [单调队列] hdu 3415 Max Sum of Max-K-sub-sequence
    java 内存数据存储
  • 原文地址:https://www.cnblogs.com/jeacy/p/13560379.html
Copyright © 2011-2022 走看看