【问题标题】:Mongo Date Query issueMongodb日期查询问题
【发布时间】:2021-02-04 23:17:17
【问题描述】:

我正在尝试从 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 天的活动日期的所有信息。所以我使用了以下查询:

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 字段检索过去一个月的结果的最佳方法是什么?例如,如果我想在每个月的第一天运行此报告以检索上个月的记录?

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

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

    如果您只想要匹配的第一个元素(适用于该示例文档),请在投影中使用 $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]}
                  ]}
             }}
        }}
    ])
    

    【讨论】:

    • 非常感谢您的意见。我尝试了上面列出的两个选项。第一个查询效果很好。然而第二个返回一些语法错误:错误:第 5 行:意外标记:在我看来,可能缺少一些括号,所以我尝试添加右括号,但仍然给我错误。从消息来看,它似乎在抱怨第 5 行,输入:“$activities”?
    • 是的,我把那个打错了。现在已经修好了。
    • 谢谢乔。这次修改后的查询没有返回错误,但结果集似乎不正确。它返回没有 dateofActivity 值的记录。有什么问题吗?
    • 它似乎适用于示例数据:mongoplayground.net/p/uXq8EDyyTYG你能提供它不工作的例子吗?
    • 奇怪的是,从原始集合中,当我使用第二个选项时,我得到了一些带有 "activities" : [] 值的数据。但是,当我创建另一个集合并插入所有具有“活动”:[] 值的记录时,查询不会返回具有“活动”:[] 的那些文档。我不知道为什么。所以这可能不是数据问题,因为使用相同的数据集和相同的查询,我有一次使用现有的集合得到了错误的数据,但是当我创建新的集合并插入相同的数据时得到了正确的数据。我测试了多次。很奇怪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 2017-06-01
    • 2021-01-21
    • 2020-04-17
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多