解決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 ( )

根據問題描述,應該是內存問題,按照我的性格,當然先百度一下(有谷歌的通知勿噴,最近FQ老是出問題),大多數寫的都是遞歸造成的問題描述,我靠,這和我情況一毛錢關系沒有,故轉而還是自己想辦法,經過一番折騰,發現,只有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();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM