【问题标题】:NodeJS MongDB queryNodeJS MongoDB 查询
【发布时间】:2017-10-11 20:25:50
【问题描述】:

我正在使用 NodeJS 和 MongoDB 数据库构建一个 webapp。目前以下内容让我感到沮丧 - 我缺乏对回调/(a)同步元素的理解并且仍在学习这一点,所以我认为它与这方面有关。

我有两个主要模块:

DB.js 导出 - 此函数在自行调用时起作用:

DB.GetSuggestions: function(searchTerm) {
    return MongoClient.connect(url).then(function(db) {
        var collection = db.collection("AccentPairs");
        collection.updateMany(
            {Unstressed: searchTerm},
            {$inc: {QueryCount: 1}}
        );
        var result = collection.aggregate([
            { $match: { Unstressed: searchTerm } },
            { $group: { _id: {"WordID": "$WordID", "WordName": "$WordName", "Unstressed": "$Unstressed", "Stressed": "$Stressed", "TranslationEn": "$TranslationEn"}, Forms: { $push: "$Field" }}}
        ]).sort( { Chosen: -1} ).toArray();
        db.close();
        return result;
    });
}

TextHandler.js:

var DB = require("../DB");

function ImportText(Text) {
  var fullText = Text.trim();
  var TextObject = {AuthorName: "", Title: "", Words: []};
  var currentWord = "";
  var BOS = true;
  var EOS = false;
  let reg = /([а-яА-ЯЁё́]+)([^а-яА-ЯЁё́]*)/g;
  var result;
  while (result = reg.exec(fullText)) {
    BOS = EOS;
    EOS = (result[2].indexOf(".") > -1);
    currentWord = result[1];
    WordObject = {WordText: result[1], WordID: "0", Options: [], Tail: result[2], BOS: BOS, EOS: EOS};
    TextObject.Words.push(WordObject);
  }
  //This is what doesn't work - GetSuggestions within the loop doesn't work.
  TextObject.Words.forEach(function(wd){

    console.log(wd.WordText);
    DB.GetSuggestions(wd.WordText).then(function(suggestions){
      wd.Options = suggestions;
    });
  });
}

我正在尝试遍历 TextObject.Words 数组并使用 GetSuggestions 函数在数据库中搜索建议。在循环内调用 GetSuggestions 不起作用,在循环外它起作用。

错误信息:

29335 ms: Mark-sweep 1386.5 (1440.6) -> 1386.5 (1440.6) MB, 1156.9 / 0.7 ms [分配失败] [GC in old space req 使用]。 30456 ms:标记扫描 1386.5 (1440.6) -> 1387.5 (1424.6) MB,1120.6 / 0.7 ms [最后的 gc]。 31576 毫秒:标记扫描 1387.5 (1424.6) -> 1388.4 (1424.6) MB,1119.4 / 0.7 毫秒 [最后的 gc]。

==== JS 堆栈跟踪 ========================================= =

安全上下文:000001186EBCFB49 1: /* 匿名 /(aka / 匿名 */) [C:\Home\CS\TextAnalysis\Ezhik\node_modules\mongodb\lib\url_parser.js:~7] [p c=000003CC6CBB279E](这=000001186EB04381​​,url=0000004FD766F421) 2:参数适配器框架:2->1 3:连接(又名连接)[C:\Home\CS\TextAnalysis\Ezhik\node_modules\mongodb\lib\mongo_client.js:~390] [pc=000...

致命错误:CALL_AND_RETRY_LAST 分配失败 - JavaScript 堆内存不足

【问题讨论】:

  • 您收到什么错误?
  • 期望会发生什么? 实际上会发生什么?
  • 没有错误 - 它只是卡在循环中。编辑:更新帖子。
  • ImportText 在哪里调用?
  • 我没有复制整个模块以节省空间。 ImportText 从 Texthandler.js 中的另一个函数调用 - 一个打开和读取特定文件夹中文本文件的函数。

标签: javascript node.js mongodb


【解决方案1】:

您不能以这种方式将 forEach 与 Promisified GetSuggestion 调用一起使用。请使用 Promises 通过 TextObject 进行迭代。请参阅以下链接(#mistake number 2)以了解如何将 Promises 用于此类场景。

【讨论】:

  • 太棒了 - 我认为这可能是这种性质的东西。我的所作所为感觉不对。看来我需要研究 Promise。
  • 如果这能解决您的问题,请告诉我们,因为我对可能是什么问题有另一种预感。
  • @223seneca 我仍然没有修复它......虽然我对承诺/(a)同步的把握不是太强。已决定通过一些教程。很高兴听到你的预感:)
【解决方案2】:

由于您收到“JavaScript heap out of memory”错误,并且由于相关函数在循环外调用时有效,因此您不知何故陷入了无限循环。这使用while 循环相对容易,您在TextHandler.js 中使用它。

我怀疑您的问题是以下一项或多项:

  1. DB.GetSuggestions 没有正确导入 TextHandler.js。当函数不在迭代循环内时,您能否确认该函数TextHandler.js内工作?
  2. while 循环应使用=====(尝试两者)来比较其条件,而不是=
  3. ImportText 中创建一个新的未定义变量result,并在下一行中将它用于while 循环的比较条件。您可能不打算在此处未定义 result,这可能会导致您的无限循环(假设 reg.exec(fullText)) 正常工作)。

如果这些步骤有帮助,请告诉我。

【讨论】:

    【解决方案3】:
     TextObject.Words.forEach(function(wd){ // iteration
    
        console.log(wd.WordText);
        DB.GetSuggestions(wd.WordText).then(function(suggestions){ // async block
          wd.Options = suggestions;
        });
      });
    

    您正在迭代异步块DB.GetSuggestions(wd.WordText),它不等待异步块完成并继续迭代中的下一个项目。你需要 Promises 来轻松处理异步函数。你可以你的Promise.all

    我从“Iterate over async function”中找到了与您的问题最相关的答案

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      • 2018-07-19
      • 2018-05-15
      • 2017-07-16
      相关资源
      最近更新 更多