0

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')}}]}});

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Yes sir, exactly what I was looking for. Thanks for the help!
1

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

2 Comments

I am familiar with $gte, $lte, etc. but I was not able to get this to work. Can you provide a sample query? For example I want all documents with a value in 'def' that have a date greater than '11/30/2010'
thanks for the help, not exactly what I was looking for but I appreciate the effort.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.