Mongoose 在 forEach() 中保存相同的文档

Posted

技术标签:

【中文标题】Mongoose 在 forEach() 中保存相同的文档【英文标题】:Mongoose saving same document in forEach() 【发布时间】:2021-07-27 10:41:13 【问题描述】:

我正在尝试创建一个网站,为我个人感兴趣的球队展示几场即将举行的足球比赛。

我正在使用 forEach() 来循环遍历球队 ID 列表,并为每个球队调用一个 api 来获取他们即将到来的比赛数据并使用 mongoose save() 将其保存到 mongodb 集合中

我遇到了一个错误,即同一个文档被多次保存并以随机顺序保存,尽管我编写了代码来解决这个问题。我认为可能存在一些关于异步的基本错误,因为我仍在学习 node.js。

我们将不胜感激!

var request = require("request");
const Match = require("../models/matchSchema");
const moment = require("moment-timezone");

const team_id = [
  "40", //liv
  "33", //utd
  "47", //tot
  "49", //chel
  "541", //Real
];

const newMatches = () => 
  team_id.forEach((element) => 
    const options = 
      method: "GET",
      url: "https://v3.football.api-sports.io/fixtures",
      qs: 
        team: element,
        next: "1",
      ,
      headers: 
        "x-rapidapi-host": "v3.football.api-sports.io",
        "x-rapidapi-key": <myAPIkey>,
        "Content-Type": "application/json",
      ,
    ;
    request(options, async (error, response, body) => 
      data = JSON.parse(body);
      if (error) throw new Error(error);

      const newMatch = await Match.findOne(
        outcomeID: data.response[0].fixture.id,
      );

      //to ensure the match doesnt exist

      if (!newMatch) 
        const newMatchCreate = await Match.create(
          outcomeID: data.response[0].fixture.id,
          category: "soccer",
          team1: data.response[0].teams.home.name,
          team2: data.response[0].teams.away.name,
          timeStart: moment
            .utc(data.response[0].fixture.date)
            .format("MM-DD HH:mm"),
        );
        await newMatchCreate.save();
      
    );
  );
;

module.exports = newMatches;

【问题讨论】:

【参考方案1】:

您似乎已将await 用于调用以同步您对Match.create()save() 的调用,我猜该新对象将写入文件。但是您忽略了request() 调用是异步的,并且仅在服务器响应其请求时才运行其回调函数。所以整个循环可能在第一个请求回调运行之前完成。然后文件以任意顺序保存。

我无法确切地知道发生了什么以及您期望什么,所以我不确定应该写入一个或多个文件以及何时写入,但通过将其记录为,确保您假设的数据按预期存在一旦它出现或在你迭代之前或其他任何东西。

【讨论】:

以上是关于Mongoose 在 forEach() 中保存相同的文档的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Foreach 中同步运行 Mongoose Find

Node.JS + Mongoose 回调地狱

nodejs中的异步foreach和mongoose

如何在不选择模式配置参数的情况下使用 mongoose 在 MongoDB 模式实例化中的关联数组/对象中执行 foreach?

Mongoose 错误 - 具有相同型号名称的 Mongoose 型号

Promise 在 forEach 循环完成之前解决