MongoDB - 基于日期返回查询

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

我在mongodb中有这样的数据

{ 
    "latitude" : "", 
    "longitude" : "", 
    "course" : "", 
    "battery" : "0", 
    "imei" : "0", 
    "altitude" : "F:3.82V", 
    "mcc" : "07", 
    "mnc" : "007B", 
    "lac" : "2A83", 
    "_id" : ObjectId("4f0eb2c406ab6a9d4d000003"), 
    "createdAt" : ISODate("2012-01-12T20:15:31Z") 
}

如何查询

db.gpsdatas.find({'createdAt': ??what here??})
,使其从数据库返回上述数据结果给我?

mongodb mongodb-query
12个回答
603
投票

您可能想要进行范围查询,例如,在给定日期之后创建的所有项目:

db.gpsdatas.find({"createdAt" : { $gte : new ISODate("2012-01-12T20:15:31Z") }});

我使用

$gte
(大于或等于),因为这通常用于仅日期查询,其中时间部分为 00:00:00。

如果你真的想找到一个等于另一个日期的日期,语法是

db.gpsdatas.find({"createdAt" : new ISODate("2012-01-12T20:15:31Z") });

33
投票

刚刚使用 Node v0.12.7 和 v4.4.4 在 Mongo v3.2.3 中实现了类似的东西并使用了:

{ $gte: new Date(dateVar).toISOString() }

我传入 ISODate (例如 2016-04-22T00:00:00Z),这适用于带或不带 toISOString 函数的 .find() 查询。但是当在 .aggregate() $match 查询中使用时,它不喜欢 toISOString 函数!


21
投票

如果您想在该日期的任何地方获取商品,您需要比较两个日期

您可以像这样在第一个日期之外创建两个日期,以获得一天的开始和一天的结束。

var startDate = new Date(); // this is the starting date that looks like ISODate("2014-10-03T04:00:00.188Z")

startDate.setSeconds(0);
startDate.setHours(0);
startDate.setMinutes(0);

var dateMidnight = new Date(startDate);
dateMidnight.setHours(23);
dateMidnight.setMinutes(59);
dateMidnight.setSeconds(59);

### MONGO QUERY

var query = {
        inserted_at: {
                    $gt:morning,
                    $lt:dateScrapedMidnight
        }
};

//MORNING: Sun Oct 12 2014 00:00:00 GMT-0400 (EDT)
//MIDNIGHT: Sun Oct 12 2014 23:59:59 GMT-0400 (EDT)

16
投票

如果你想得到过去5分钟内的所有新东西,你就必须做一些计算,但这并不难......

首先在要匹配的属性上创建索引(包括排序方向-1表示降序,1表示升序)

db.things.createIndex({ createdAt: -1 }) // descending order on .createdAt

然后查询最近 5 分钟(60 秒 * 5 分钟)创建的文档......因为 javascript 的

.getTime()
返回毫秒,因此您需要将其乘以 1000,然后才能将其用作
new Date()
构造函数的输入。

db.things.find({
        createdAt: {
            $gte: new Date(new Date().getTime()-60*5*1000).toISOString()
         }
     })
     .count()

new Date(new Date().getTime()-60*5*1000).toISOString()
的解释如下:

首先我们计算“5分钟前”:

  1. new Date().getTime()
    为我们提供当前时间(以毫秒为单位)
  2. 我们想从中减去 5 分钟(以毫秒为单位):
    5*60*1000
    - 我只需乘以
    60
    秒,这样就很容易更改。如果我想要 2 小时(120 分钟),我可以将
    5
    更改为
    120
  3. new Date().getTime()-60*5*1000
    给我们
    1484383878676
    (5 分钟前,以毫秒为单位)

现在我们需要将其输入到

new Date()
构造函数中以获取 MongoDB 时间戳所需的 ISO 字符串格式。

  1. { $gte: new Date(resultFromAbove).toISOString() }
    (mongodb .find() 查询)
  2. 由于我们不能有变量,所以我们一次性完成所有操作:
    new Date(new Date().getTime()-60*5*1000)
  3. ...然后转换为 ISO 字符串:
    .toISOString()
  4. new Date(new Date().getTime()-60*5*1000).toISOString()
    给了我们
    2017-01-14T08:53:17.586Z

当然,如果您使用的是 node-mongodb-native 驱动程序,那么使用变量会更容易一些,但这适用于 mongo shell,这是我通常用来检查的东西。


13
投票

查找特定日期:

db.getCollection('CollectionName').find({"DepartureDate" : new ISODate("2019-06-21T00:00:00.000Z")})

查找较大

gte
或较小
lt
:

db.getCollection('CollectionName').find({"DepartureDate" : { $gte : new ISODate("2019-06-11T00:00:00.000Z") }})

按范围查找:

db.getCollection('CollectionName').find({ 
    "DepartureDate": { 
        $lt: new Date(), 
        $gte: new Date(new Date().setDate(new Date().getDate()-15))
      } 
    })

6
投票

您也可以尝试:

{
    "dateProp": { $gt: new Date('06/15/2016').getTime() }
}

2
投票

如果您使用 Mongoose,

try {
  const data = await GPSDatas.aggregate([
    {
      $match: { createdAt : { $gt: new Date() }
    },
    {
      $sort: { createdAt: 1 }
    }
  ])
  console.log(data)

} catch(error) {
    console.log(error)
}

1
投票

就个人而言,我更喜欢避免使用客户端 JavaScript 处理/第三方库(如 moment.js),以避免客户端和服务器端之间的时区处理不一致。

  1. 基于范围的查询
db.collection.find({
  "createdAt": {
    $gte: ISODate("2012-01-12T00:00:00Z"),
    $lt: ISODate("2012-01-13T00:00:00Z")
  }
})
  1. 使用
    $dateFromParts
  2. 构建日期范围
db.collection.find({
  $expr: {
    $gte: [
      "$createdAt",
      {
        "$dateFromParts": {
          "year": 2012,
          "month": 1,
          "day": 12
        }
      }
    ]
  }
})
  1. 获取日期差异范围(例如当前日期之前 15 年)
db.collection.find({
  $expr: {
    $gte: [
      "$createdAt",
      {
        "$dateSubtract": {
          "startDate": "$$NOW",
          "unit": "year",
          "amount": 15
        }
      }
    ]
  }
})

0
投票

如果您使用的是 mongodb 聚合,那么代码如下:

  1. 这里我将 dd/mm/yyyy 日期转换为 ISO 日期(bcoz 日期以 ISO 日期格式存储在 db 中)

const dateToIso=(from, to)=>{
    return {
        fromIsoDate: moment(from,"DD/MM/YYYY").toISOString(),
        toIsoDate: moment(to,"DD/MM/YYYY").add(1,'days').toISOString()
    }
}

  1. 最后使用 mongodb 聚合得到这些值:

{
                $match:{
                    $and:[
                        {
                            createdAt:{
                                $lte: new Date(toIsoDate)
                            }
                        },
                        {
                            createdAt:{
                                $gte: new Date(fromIsoDate)
                            }
                        },
                        
                    ]
                }
            },


0
投票

每当您必须处理

Date
值时,我建议使用第 3 方日期库,例如 moments.jsLuxonDay.js

  {
    $match: {
      createdAt: { $gte: DateTime.fromISO(date).toJSDate() }
    }
  }

createdAt: { $gte: moment().toDate() }

对于普通的

Date
值,没有任何区别,即您可以使用原生
new Date(...)
ISODate(...)
。但是,当您必须处理时区或其他数学(例如
beginOf('hour')
endOf('week')
add({days:7,months:1})
等)时,这些库比原生 JavaScript
Date
对象更易于使用且可预测性更好。


-1
投票

我喜欢使用颠倒日期:

{ 
    ...
    "createdAt" : 120112201531
}

在本例中,日期格式为“YYMMDDHHmmsss”(2 位年份 + 2 位月份 + 2 位日期 + 2 位小时 + 2 位分钟 + 2 位秒)。

然后你可以进行搜索:

db.gpsdatas.find({"createdAt" : { $gte : 120112201531 }})

它更具可读性且易于编程。如果您想使用没有时间的日期过滤器,那就更好了,因为您可以使用索引类型来提高日期格式(如“YYYYMMDD”)的性能。

要将此字符串格式呈现为 JavaScript 中的日期对象,您可以使用 DayJS 等模块和 CustomParseFormat 插件:

const date1 = dayjs('120112201531', 'YYMMDDHHmmsss')
const date2 = dayjs('20120112', 'YYYYMMDD')

https://day.js.org/docs/en/plugin/custom-parse-format


-3
投票

如果您想从日期时间获取记录,可以使用以下命令:

(mongodbCompass 3.6.8 与 PyMongo)

mongo.db.collection.aggregate([{"$match":{"object.object.key":{"$gte":ISODate('2021-01-27T00:00:00Z').toISOString()}}}])

db.collection.find({"object.object.key":{"$gte":ISODate('2021-01-27T00:00:00Z').toISOString()}})
© www.soinside.com 2019 - 2024. All rights reserved.