MongoDB: Find all documents except those where a date range condition matches

Requirement: I want a collection of all customers who did not perform the "View" event in last 5 hours .

Data:

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

I have tried out the following, but it always returns "Sheldon" (possibly because the other event ends up satisfying the criteria?).

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

What can I do so that only documents for "Leonard" and "Raj" are returned?


To get users how has not visited in last 5 hours. you can try it

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

This query returned only documents for Leonard and Raj for your given example

NB: Like your query but I used find instead of where , no need to use $and and used $gt instead of $gte

Tested for documents.

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

After apply my query result:

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

When I run your query with your exact data, the Sheldon document gets returned because when you compare the string "2 hours ago" to the string "5 hours ago", the character "2" is less than the character "5" so the document gets correctly returned. The string "10 hours ago" is also sorted as being less than "5 hours ago".

However if you adjust the data to have actual numbers like below, the Sheldon document is not returned.

So your query looks good to me, you just need to replace the timestamps with either Dates, numbers, or even strings that are structured so that they will sort in the correct order.

Modified Data:

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

Modified Query:

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

Result:

{ "name" : "Leonard", "events" : [ { "event" : "View", "timestamp" : -10 } ] }
{ "name" : "Raj", "events" : [ { "event" : "Some other event", "timestamp" : -6 } ] }
链接地址: http://www.djcxy.com/p/38824.html

上一篇: Git rebase递归分支

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