MongoDB:查找除日期范围条件匹配的文档之外的所有文档

时间:2017-03-29 09:03:41

标签: node.js mongodb mongoose

要求:我想要一个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"的文档?

2 个答案:

答案 0 :(得分:2)

让用户在过去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的文档

NB:与您的查询一样但我使用find代替where,无需使用$and并使用$gt代替{ {1}}

为文档测试。

$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")
        }
    ]
}

答案 1 :(得分:1)

当我使用您的确切数据运行查询时,会返回Sheldon文档,因为当您将字符串" 2小时前" 与字符串&#34进行比较时; 5小时前" ,字符" 2" 小于字符" 5" 所以文档被正确返回。字符串" 10小时前" 的排序也小于" 5小时前"

但是,如果您将数据调整为具有如下所示的实际数字,则不会返回Sheldon文档。

因此,您的查询对我来说很好,您只需要将时间戳替换为日期,数字,甚至是结构化的字符串,以便它们按正确的顺序排序。

修改后的数据:

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

修改后的查询:

{ 
    $and: [
        {
            'events': { 
                $not: { 
                    $elemMatch: {
                        event: "View",
                        timestamp: {
                            $gte: -5
                        }
                    }
                }
            }
        }
    ]
}

<强>结果:

{ "name" : "Leonard", "events" : [ { "event" : "View", "timestamp" : -10 } ] }
{ "name" : "Raj", "events" : [ { "event" : "Some other event", "timestamp" : -6 } ] }