首页 > 解决方案 > Mongo 并不总是返回正确的结果

问题描述

我有一个处理排队的 JSON 请求的 nodeJS 脚本。我们查询 Mongo (v3.6.3) 以获取要处理的请求队列,然后在队列上执行 forEach。我们使用 Promise 和 async / await 查询我们的 API 端点来解析请求。

我们执行 Mongo 查询以查看过去 3 天是否有患者的现有记录。我们使用 findOne 或 find limit 1 查找患者 ID 和药房 ID(已尝试两种方法来解决问题)。如果我们有现有记录,我们会对现有记录执行更新。否则,我们创建一个新文档。这似乎在大多数情况下都有效。但是,有时每个排队的条目都会导致创建一个新文档。因此,如果我们有 4 个患者队列中的整体,我们将创建 4 个遭遇。我们可以清空数据库,再次处理队列,就可以正常工作了。它似乎在绝大多数时间都有效。该过程可以开始工作,然后在开始后不久开始中断。一旦我们创建了一个重复记录,队列中的所有其他项目最终都会被创建为新条目。

我认为这个问题与 Mongo 没有正确返回数据有关。有没有人目睹过这样的事情?

我们最近切换到 find and limit 1 看看是否有帮助。我们已经多次处理队列并且代码有效并且不会导致重复。当我们处理当天的第一个队列时,我们注意到重复似乎发生了。但是一天中的第一个队列并不总是导致错误。然而,这可能而且很可能是巧合。

我们如何查询和处理队列

  let token;
  (async () => {
    // Get Access Token
    token = await authenticate();

        PharmacyQueue.find({ $and: [{ archive: false }, { date: { $gte: today } }] })
      .then(results => {
        let queue = [];
        results.forEach(request => {
          queue.push(JSON.parse(request.rawJSON));
          request.archive = true;
          request.save().catch(err => {
            console.log('Unable to archive');
          });
        });

        return queue;
      })
      .then(async requests => {
        for (const request of requests) {
          let response = await parseRequest(token, request);
          // SLEEP NOT NEEDED - JUST ADDED TO GIVE US TIME TO WATCH DEBUG LOGS
          await sleep(1000);
          console.log(response);
        }
      })
      .then(() => {
        mongoose.disconnect();
      })
      .catch(err => console.log(err));
  })();

用于搜索现有记录的 API 上的代码 - 问题发生的位置。我们刚刚从 findOne 切换到 find 限制为 1

 // Search For existing Encounter
  PharmacyEncounter.find(
    {
      $and: [
        {
          'patient.patientId': patient.patientId
        },
        {
          'pharmacy.ehrId': pharmacy.ehrId
        },
        {
          date: {
            $gt: threeDaysAgo
          }
        },
        {
          date: {
            $lte: moment(today)
              .endOf('day')
              .toDate() //today +'T23:59:59'
          }
        }
      ]
    },
    '-rawJSON -analytics'
  )
    .limit(1)
    .then(results => {
      if (
        results &&
        results[0] &&
        results[0].patient.patientId
      ) {
        console.log('Encounter Exists');
        // Encounter Already exists

        // Check if Prescription is already attached to encounter
        let desc = 'Appended medication';
        results[0].prescription.filter(presc => {
          if (presc.rxNumber == prescription.rxNumber) {
            // Existing Medication with same rxNumber found

            // Get remove index
            const removeIndex = results[0].prescription
              .map(item => item.rxNumber.toString())
              .indexOf(prescription.rxNumber);
            // Splice out of array
            results[0].prescription.splice(removeIndex, 1);
            desc = 'Updated medication';
          }
        });

        // Append Prescription ( updated or new )
        results[0].prescription.push(prescription);
        results[0]
          .save()
          .then(savedRx => {
            res.json({
              status: 'SUCCESS',
              id: savedRx._id,
              desc
            });
          })
          .catch(err => {
            const error = JSON.stringify(err);
            res.status(500).json({ status: 'ERROR', desc: error });
          });
      } else {
        // New Encounter - Create Encounter
        ... more code here to process new encounter ...
      }

标签: javascriptnode.jsmongodbmongoose

解决方案


threeDaysAgo 和 today 变量是包含在请求之外的常量。因此,当节点应用程序启动时,它们被设置为不可变的。Mongo 会在第二天返回正确的结果。然后 mongo 将停止提供“正确”的结果。我将对代码进行更改以进行测试,并且 nodemon 重新启动了服务器,解决了另一天的问题。


推荐阅读