首页 > 解决方案 > Mongo 日期查询问题

问题描述

我正在尝试从 Mongo 数据库的集合中检索过去一个月的一些数据,它应该每个月运行一次,所以我想要一个可以在每月的第一天运行的查询,以根据查询生成报告。所以我试图使用 $lt 和 $gte 来限制日期范围。需要过滤的日期是数组中的一个值。例如:下面是集合名称为 Test 的集合数据:

{
    "_id" : ObjectId("1234528f4a224cdb39aaa"),
    "Project" : "12345",
    "Department" : "Sales",
    "Summary" : "TEST",
    "FirstName" : "Mary",
    "LastName" : "White",
    "activities" : [ 
        {
            "Type" : "Trip",
            "dateOfActivity" : ISODate("2020-12-20T06:00:00.000Z")
        }, 
        {
            "Type" : "Conference",
            "dateOfActivity" : ISODate("2021-01-05T06:00:00.000Z"),
            "Note" : "test"
        }
    ]

所以我想运行一个查询来检索过去 15 天的 dateofActivity 的所有信息。所以我使用了以下查询:

db.Test.find( { 'activities.dateOfActivity': { $lt: new Date(), $gte :new Date(new Date().setDate(new Date().getDate()-15)) }})

然后我注意到返回记录不限于过去 15 天内的所有活动。然后我尝试运行查询:

db.Test.find( { 'activities.dateOfActivity': { $gte : ISODate("2021-02-04T06:00:00.000Z")}})

这也不限制查询记录。返回的记录包含 2020 年 12 月 27 日的一些数据。我在哪里做错了查询?

另外,根据这个 dateofActivity 字段检索过去一个月的结果的最佳方法是什么?例如,如果我想在每个月的第一天运行此报告以检索上个月的记录?

标签: mongodbmongodb-query

解决方案


有几个选项可用于过滤响应中的数组。

如果您只想要匹配的第一个元素(适用于该示例文档),请$elemMatch在投影中使用:

db.Test.find( {'activities.dateOfActivity': { $gte: date2, $lte: date1 }}, {activities: {$elemMatch:{dateOfActivity:{$gte: date2, $lte: date1})

如果您需要获取每个匹配的元素,则需要使用聚合。

使用展开:

  • 匹配以将管道的其余部分限制为具有至少一个匹配日期的文档
  • 展开活动数组
  • 仅匹配日期范围内的那些活动
db.Test.aggregate([
   {$match: { 'activities.dateOfActivity':  { $gte: date2, $lte: date1 }}},
   {$unwind: "$activities"},
   {$match: { 'activities.dateOfActivity':  { $gte: date2, $lte: date1 }}}
])

使用过滤器:

  • 匹配以选择具有匹配日期的文档
  • 使用过滤器迭代每个活动数组以消除不匹配的元素
db.Test.aggregate([
   {$match: { "activities.dateOfActivity":  { $gte: date2, $lte: date1 }}},
   {$addFields: { 
         activities: {$filter: {
              input: "$activities",
              cond: {$and: [
                       {$gte: [ "$$this.dateOfActivity", date2]},
                       {$lte: [ "$$this.dateOfActivity", date1]}
              ]}
         }}
    }}
])

推荐阅读