Javascript 在MongoDB中使用$lt和$gt筛选日期值

Javascript 在MongoDB中使用$lt和$gt筛选日期值,javascript,node.js,mongodb,date,Javascript,Node.js,Mongodb,Date,在我的MongoDB/节点后端,我正在设置一个函数,该函数接受用户输入的筛选值,并通过GET请求相应地筛选数据。这在很大程度上是可行的。大多数过滤器按预期返回记录 然而,事实证明,按出生日期(dob)过滤是有问题的。具体而言,当同时获取dobBefore和dobAfter的值时,结果是不正确的。根据我看到的记录,我没有得到预期返回的日期范围 对于我的筛选代码,如果有一个输入值,我首先将其转换为日期(与我们的数据库值(即日期)相匹配),然后我运行搜索以仅返回dob为输入日期值之前的日期(使用$lt

在我的MongoDB/节点后端,我正在设置一个函数,该函数接受用户输入的筛选值,并通过GET请求相应地筛选数据。这在很大程度上是可行的。大多数过滤器按预期返回记录

然而,事实证明,按出生日期(dob)过滤是有问题的。具体而言,当同时获取dobBefore和dobAfter的值时,结果是不正确的。根据我看到的记录,我没有得到预期返回的日期范围

对于我的筛选代码,如果有一个输入值,我首先将其转换为日期(与我们的数据库值(即日期)相匹配),然后我运行搜索以仅返回dob为输入日期值之前的日期(使用$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=1d1和token=ffb4bbb3

正如我前面所说,虽然我应该只看到dob在1998-12-06之前和1998-02-06之后的记录(因此在这10个月的范围内),但我没有看到返回的记录中反映出这一点。例如,这是从上述查询返回的记录之一(明显超出了目标范围):

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

这里是否有日期和$lt和$gt操作符的问题?还是我还遗漏了什么

编辑/更新:

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


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

您正在用$gt值覆盖dob键

你想要

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


您可能需要更改日期格式。请参见如何在文档中存储日期?我建议附上一些示例文档。在文档中,我存储的日期如下:“1998-12-01T06:00:00.000Z”。类型是“日期”。我不确定你指的是什么问题。对于此代码:搜索['dob']={$gt:dobAfterDate};--即有效地检查“dob”字段,并返回dob晚于/大于存储在DOBFerDate变量中的输入日期值的记录。对吗?也许问题是我需要转换为am ISODate。我说的是你的代码有一个bug,如果你想进行范围搜索,即dob字段在你发布的代码之前和之后的日期之间,将无法工作。只有在使用$lt或$gt时,您的代码才会工作。执行$lt或$gt搜索时,您会得到什么?您的结果是否缺少预期的文档?因此您的范围查询无法正常工作?如果是,这正是发布代码的结果。首先执行
“dob”:{“$lt”:date1}
,然后使用
“dob”:{“$gt”:date2}
覆盖它。所以发送到服务器的查询是
“dob”:{“$gt”:date2}
好的,我明白你的意思了。我需要以某种方式组合查询,并一次性查询,而不是在两个单独的请求中查询。
1998-12-01T06:00:00.000Z
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 };
}
{"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)