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

要求:我要收集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"被退回?

为了让用户在最近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

testing的文件。

 { "_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" } 

当我用您的确切数据运行查询时,谢尔顿文档被返回,因为当您将string“2小时前”与string“5小时前”比较时 ,字符“2”小于字符“5”文件得到正确返回。 string“10小时前”也被sorting为小于“5小时前”

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

所以你的查询看起来不错,你只需要用date,数字,甚至string来replace时间戳,这样就可以按照正确的顺序sorting。

修改的数据:

 { 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 } ] }