使用 .find() 方法按日期过滤 MongoDB 集合会忽略一些记录

问题描述 投票:0回答:1

我正在尝试使用 MongoDB 节点包按日期和

.filter()
$gte
运算符来
$lte
我的 MongoDB 集合。它根本没有按预期工作,并且遗漏了一些记录。我花了几个小时谷歌搜索并试图找出为什么会发生这种情况,但我已经不知道了。

在屏幕截图中,您可以看到我的记录的完整列表。我正在尝试按

dateinvoice
字段进行过滤。例如。大于 2024 年 4 月 29 日。它应该返回 7 条记录,但下面的代码省略了发票号码
00174-2024
,如第二个屏幕截图所示。

enter image description here

这是我的代码:

const df = req.query.dateFrom;
const query = {};
query['dateinvoice'] = { $gte: new Date(df).toISOString() };

const count = await db
  .collection('invoices')
  .find(query)
  .sort({_id: -1})
  .toArray();

查询确实发生了,但是结果遗漏了一些应该有但没有的记录。

enter image description here

它至少缺少 1 条记录,在 MongoDB Atlas 集合浏览器中可以看到:

enter image description here

我尝试过不同的查询,例如

query['dateinvoice'] = { $gte: new Date(df) };
query['dateinvoice'] = { $gte: df }
,但每种变化都会给我不同的错误结果。

我在这里做错了什么?

node.js mongodb next.js mongodb-query
1个回答
0
投票

$dateFromString 和 $toDate 都将在第一次错误时停止操作,即无法将给定字符串转换为日期对象。这就是本例中发生的情况。请您先评估一下资料,并致电询问如何处理错误的文件。以下示例文档和操作日志可能会提供更多详细信息。

样本文件

xyz> use test
test> t = db.test;
test> t.drop()
test> t.find();
[
  {
    stringdate: '06-15-2008'
  },
  {
    stringdate: 'oct 20 2020'
  },
  {
    stringdate: '2017-02-08'
  },
  {
    stringdate: '2017-02-08T12:10:40.787'
  },
  {
    stringdate: '2017-02-08T12:10:40.787'
  }
]

行动日志

首先检查文件是否有错误。请注意,以下查询不会因错误而停止。这是通过OnError 实现的。这意味着在转换给定文档失败时,将提供 OnError 上给出的值。这对于识别错误文档很有用。在示例案例中,有一份这样的文档。此查询仅过滤此类文档并使用 _id 和旧日期值显示它。

test> t.aggregate([{ $project: { newdate: { $dateFromString: { dateString: '$stringdate', onError:'error' } },stringdate:1}},{$match:{newdate:'error'}}]);
    [
      {
        _id: ObjectId('6641ad7451d50517dda0deea'),
        stringdate: '06-15-2008',
        newdate: 'error'
      }
    ]

以上查询结果将有助于评估文档。并打电话询问如何处理。在示例案例中,只有一份不可转换的文档。这应通过以下查询来纠正。

t.update({stringdate:'06-15-2008'}, { $set:{stringdate:'2008-06-15'}});

现在,当我们在步骤 1 中运行查询时,它不会生成任何文档。作为可选检查,还可以运行以下查询。它将计算该键中的类型数量并显示每种类型的计数。理想情况下,它应该只生成日期类型,并且计数应该根据集合中的文档进行。这可以确保转换过程完成并且键只有日期类型值。

t.aggregate([{$group:{_id:{$type:"$stringdate"},count:{$sum:1}}}]);
[ { _id: 'date', count: 5 } ]

请求您可以根据上述查询的输出来评估您的收藏。并查看有多少文档无法转换。通过查看音量,您将能够接听是否可以进行手动校正的电话。更正此类文档后,您的第一个查询本身就足以完成工作。请注意其中的以下修改,$toDate 和 $dateFromString 本质上是相同的,因此只需一个就足够了。

db.collection.updateMany( { QCDate: { $exists: true } }, [ { $set: { QCDate: { $dateFromString: { dateString: "$QCDate" } }  } } ] )

注意: 如果发现需要纠正的记录较多,则可能需要对错误文档进行进一步分析以实现可能的自动化。然而,所需过程的基本性质保持不变 - 数据校正。

© www.soinside.com 2019 - 2024. All rights reserved.