【问题标题】:Filtering Date Values Using $lt and $gt in MongoDB在 MongoDB 中使用 $lt 和 $gt 过滤日期值
【发布时间】:2018-03-16 18:58:38
【问题描述】:

在我的 MongoDB/Node 后端中,我正在设置一个函数,该函数采用用户输入的过滤器值并通过 GET 请求相应地过滤数据。这在很大程度上是有效的。大多数过滤器按预期返回记录。

但是,事实证明,过滤出生日期 (dob) 存在问题。具体来说,当同时接受 dobBefore 和 dobAfter 的值时,结果是不正确的。根据我看到的记录,我没有得到预期的返回日期范围。

对于我的过滤器代码,如果有输入值,我首先将其转换为日期(以匹配我们的数据库值——即日期),然后运行搜索以仅返回 dob 所在的记录,在 dobBefore 的情况下 - 输入该日期值之前的日期(使用 $lt 运算符),在 dobAfter 的情况下 - 输入日期值之后的日期(使用 $gt 运算符)。这是有问题的代码:

  // dobBefore filter
  if (dobBefore) {
    let dobBeforeDate = new Date(dobBefore);
    console.log('dobBeforeDate: ', dobBeforeDate);
        search['dob'] = { $lt: dobBeforeDate };
  }

  // dobAfter filter
  if (dobAfter) {
    let dobAfterDate = new Date(dobAfter);
    console.log('dobAfterDate: ', dobAfterDate);
        search['dob'] = { $gt: dobAfterDate };
  }

完整的 GET 请求如下所示:

api.somesite.com/v0/customers/details?dobBefore=1998-12-06&dobAfter=1998-02-06&apikey=1d1d1d1&token=ffb4bbb3

正如我之前所说,虽然我应该只看到出生日期在 1998 年 12 月 6 日之前和 1998 年 2 月 6 日之后(因此在 10 个月范围内)的记录,但我看不到这反映在返回的记录。例如,这是从上述查询返回的记录之一(显然远远超出了目标范围):

"dob": "2007-08-23T05:00:00.000Z"

为了澄清,在文档中,dob 是这样存储的,并且是“日期”类型:

1998-12-01T06:00:00.000Z

这里有一些关于日期和 $lt 和 $gt 运算符的陷阱吗?还是我还缺少其他东西?

编辑/更新:

在得到@Veeram 的一些反馈后,我意识到我正在用另一个查询覆盖一个查询。我需要将它们结合起来。我在想这样的事情应该可以工作(顺便说一下,如果没有值,我将 dobBefore 和 dobAfter 初始化为空字符串,这就是我检查空字符串的原因):

let search = {};

// dobBefore filter
if (dobBefore && dobAfter === '') {
   let dobBeforeDate = new Date(dobBefore);
   search['dob'] = { $lt: dobBeforeDate };
}

// dobAfter filter
if (dobAfter && dobBefore === '') {
   let dobAfterDate = new Date(dobAfter);
   search['dob'] = { $gt: dobAfterDate };
}

// filter both at once
if (dobBefore && dobAfter) {
   let dobBeforeDate = new Date(dobBefore);
   let dobAfterDate = new Date(dobAfter);
   search['dob'] = { "$lt" : dobBeforeDate , "$gt" : dobAfterDate };
}

编辑/更新 2:上面的代码按预期工作。问题解决了!

【问题讨论】:

  • 您可能需要更改日期格式。请看stackoverflow.com/questions/2943222/…
  • 如何在文档中存储日期?我建议附上一些示例文件。
  • 在文档中我存储这样的日期:“1998-12-01T06:00:00.000Z”。类型为“日期”。

标签: javascript node.js mongodb date


【解决方案1】:

你正在用 $gt 值覆盖 dob 键。

你想要的

{"dob" :{
   "$lt" : ISODate("2018-03-16T19:31:01.229Z"),
   "$gt" : ISODate("2018-03-25T19:31:01.279Z")
}}

试试

let search = {dob:{}};
if (dobBefore) {
    let dobBeforeDate = new Date(dobBefore);
    console.log('dobBeforeDate: ', dobBeforeDate);
    search['dob'].$lt =  dobBeforeDate;
  }

  // dobAfter filter
if (dobAfter) {
    let dobAfterDate = new Date(dobAfter);
    console.log('dobAfterDate: ', dobAfterDate);
    search['dob'].$gt=  dobAfterDate ;
}

collection.find(search)

【讨论】:

  • 我不确定您指的是什么问题。对于此代码: search['dob'] = { $gt: dobAfterDate }; -- 这实际上是检查“dob”字段并返回dob 晚于/大于存储在dobAfterDate 变量中的输入日期值的记录。正确的?也许问题是我需要转换为 am ISODate。
  • 我说的是你的代码在你想要进行范围搜索的情况下的错误,即你发布的代码在 dateBefore 和 dateAfter 之间的 dob 字段将不起作用。只有使用 $lt 或 $gt 时,您的代码才会起作用。
  • 执行 $lt 或 $gt 搜索时会得到什么?您的结果是否缺少预期的文件?
  • 所以你的范围查询不能正常工作?如果是,那正是发布的代码会发生的情况。你先做"dob" :{ "$lt" : date1} 然后用"dob" :{ "$gt" : date2} 覆盖它。所以发送到服务器的查询是"dob" :{ "$gt" : date2}
  • 好的,我明白你在说什么。我需要以某种方式组合查询,并一次查询它,而不是在两个单独的请求中。
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
相关资源
最近更新 更多