【问题标题】:MongoDB: Find all documents except those where a date range condition matchesMongoDB:查找除日期范围条件匹配的文档之外的所有文档
【发布时间】:2017-03-29 19:53:20
【问题描述】:

需求:我想要一个集合所有did not perform the "View" event in last 5 hours的客户。

数据:

{
    name: "Sheldon",
    events: [
        {
            event: "View",
            timestamp: "timestamp equivalent to 10 hours ago"
        },
        {
            event: "Some other event",
            timestamp: "timestamp equivalent to 8 hours ago"
        },
        {
            event: "View",
            timestamp: "timestamp equivalent to 2 hours ago"
        }
    ]
},
{
    name: "Leonard",
    events: [
        {
            event: "View",
            timestamp: "timestamp equivalent to 10 hours ago"
        }
    ]
},
{
    name: "Howard",
    events: [
        {
            event: "View",
            timestamp: "timestamp equivalent to 2 hours ago"
        }
    ]
},
{
    name: "Raj",
    events: [
        {
            event: "Some other event",
            timestamp: "timestamp equivalent to 6 hours ago"
        }
    ]
}

我尝试了以下方法,但它总是返回 "Sheldon"(可能是因为其他事件最终满足了条件?)。

q.where({ 
    $and: [
        {
            'events': { 
                $not: { 
                    $elemMatch: {
                        event: "View",
                        timestamp: {
                            $gte: "timestamp equivalent to 5 hours ago"
                        }
                    }
                }
            }
        }
    ]
});

我该怎么做才能只返回 "Leonard""Raj" 的文档?

【问题讨论】:

  • 检查一次this question
  • 您可以查看 (docs.mongodb.com/manual/reference/operator/query-comparison) 了解更多详情。
  • @TanmayBaranwal 我的示例查询等同于您链接中的查询,但无法按预期工作,因为还有另一个满足条件的事件。
  • 你有 ISO 格式的日期吗?为什么不用实际日期更新您的帖子?这将使尝试回答和测试您的代码的人们变得容易。

标签: node.js mongodb mongoose


【解决方案1】:

获取过去 5 小时内未访问过的用户。你可以试试

db.collectionName.find({
    events: { 
        $not: { 
            $elemMatch: {
                event: "View",
                timestamp: {
                    $gt: ISODate("2017-03-29T05:12:37.420Z") // equivalent to 5 hours ago
                }
            }
         }
    }
}, {name: 1})

此查询 returned 仅记录您给定示例的 LeonardRaj

注意:喜欢你的查询,但我用find代替where,不需要使用$and并用$gt代替$gte

已针对文档进行测试。

{
    "_id" : ObjectId("58db886e4b9e731aaefa9820"),
    "name" : "Sheldon",
    "events" : [ 
        {
            "event" : "View",
            "timestamp" : ISODate("2017-03-29T00:09:18.723Z")
        }, 
        {
            "event" : "Some other event",
            "timestamp" : ISODate("2017-03-29T02:10:04.492Z")
        }, 
        {
            "event" : "View",
            "timestamp" : ISODate("2017-03-29T08:11:02.196Z")
        }
    ]
}
{
    "_id" : ObjectId("58db886e4b9e731aaefa9821"),
    "name" : "Leonard",
    "events" : [ 
        {
            "event" : "View",
            "timestamp" : ISODate("2017-03-29T00:11:23.084Z")
        }
    ]
}
{
    "_id" : ObjectId("58db886e4b9e731aaefa9822"),
    "name" : "Howard",
    "events" : [ 
        {
            "event" : "View",
            "timestamp" : ISODate("2017-03-29T08:11:02.196Z")
        }
    ]
}
{
    "_id" : ObjectId("58db886e4b9e731aaefa9823"),
    "name" : "Raj",
    "events" : [ 
        {
            "event" : "Some other event",
            "timestamp" : ISODate("2017-03-29T04:10:42.972Z")
        }
    ]
}

应用我的查询结果后:

{
    "_id" : ObjectId("58db886e4b9e731aaefa9821"),
    "name" : "Leonard"
},
{
    "_id" : ObjectId("58db886e4b9e731aaefa9823"),
    "name" : "Raj"
}

【讨论】:

  • 这与我在问题中提到的有什么不同?
  • 无需使用$and 并使用$gt 而不是$gte,除非您的查询应该正常工作。使用您的数据进行测试:) @hiteshspac
  • @ShaishabRoy 您编写的查询没有提供所需的输出。它重新整理了整个数据集。你能检查一下吗!
  • 我假设 timestampDate type 所以如果 timestempDate type 那么它应该可以工作。我测试了@RohitRai
猜你喜欢
  • 2021-02-24
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 2019-02-19
相关资源
最近更新 更多