Brian Evans
Brian Evans

Reputation: 245

Search array for dates within a range

I am new to MongoDB, keep that in mind as I ask my questions please. I have the following collection named 'documents' where I have an array named attributes which contains key:value pairs of different types.

{
    "_id" : ObjectId("5d376c67f6c305c7571f7dd7"),
    "name" : "testContract.pdf",
    "fileType" : "pdf",
    "attributes" : [
            {
                    "abc" : 1
            },
            {
                    "def" : ISODate("2012-12-01T08:00:00Z")
            },
            {
                    "ghi" : "test"
            }
    ]
}
{
    "_id" : ObjectId("5d376ca4f6c305c7571f7dd8"),
    "name" : "1099.pdf",
    "fileType" : "pdf",
    "attributes" : [
            {
                    "def" : ISODate("2012-06-03T07:00:00Z")
            },
            {
                    "ghi" : "taxes"
            }
    ]
}

What I would like to do is return one or more documents from this collection that fit within a date range. For example I can return all documents that have a fileType of 'pdf' with the following query -->

db.documents.find({"fileType":"pdf"}); 

But what I am trying to figure out is can I search an array containing different data types like dates in a range successfully while also being able to search for strings. I can also search the attributes array with the following -->

db.documents.find({"attributes":{"ghi":"test"}});

Here is an example of what I am trying to get but it is not working...

db.documents.find({'attributes':$match:{[{'def':{$gte:new Date('2011-11-30')}}]}});

Upvotes: 0

Views: 39

Answers (2)

DaveStSomeWhere
DaveStSomeWhere

Reputation: 2540

Is something like this what you are looking for?

Based on the following documents:

{
    "_id" : ObjectId("5d38aad64850fbd5d13f14bd"),
    "name" : "testxx.pdf",
    "attributes" : [
        {
            "abc" : 1
        },
        {
            "def" : ISODate("2012-12-01T08:00:00Z")
        },
        {
            "ghi" : "test"
        }
    ]
}
{
    "_id" : ObjectId("5d38b0eae4adbe945b6cbb89"),
    "name" : "testyy.pdf",
    "attributes" : [
        {
            "abc" : 2
        },
        {
            "def" : ISODate("2013-12-01T08:00:00Z")
        },
        {
            "ghi" : "test1"
        }
    ]
}
{
    "_id" : ObjectId("5d38b12f21e647b8d384d841"),
    "name" : "testzz.pdf",
    "attributes" : [
        {
            "abc" : 3
        },
        {
            "def" : ISODate("2012-05-01T08:00:00Z")
        },
        {
            "ghi" : "test"
        }
    ]
}

Query def > 2010/11/30 - returns all 3 docs above

db.chkdates.find({'attributes.def':{$gte:new Date(2010,11,30)}}).pretty()

Adding another key/value pair and range looks like:

db.chkdates.find({'attributes.def':{$gte:new Date(2011,12,12), 
                                    $lte:new Date(2012,10,12)},
'attributes.ghi':'test'}).pretty()

Returns only 1 document:

{
    "_id" : ObjectId("5d38b12f21e647b8d384d841"),
    "name" : "testzz.pdf",
    "attributes" : [
        {
            "abc" : 3
        },
        {
            "def" : ISODate("2012-05-01T08:00:00Z")
        },
        {
            "ghi" : "test"
        }
    ]
}

Upvotes: 1

silencedogood
silencedogood

Reputation: 3299

You can use the $gte and $lte for querying within a date range. It would look something like this:

{'def': { $gte: qryDateFrom, $lte: qryDateTo }}

Depending on if you're using aggregate pipleline or a regular mongoose query, you'd just apply this accordingly.

For instance, using $match in an aggregate with a string match included, it would look like this:

$match: { 
            $and: [
                {'id': { $ne: req.user._id }},
                {'def': { $gte: qryDateFrom, $lte: qryDateTo }}
            ]
        }

Upvotes: 1

Related Questions