Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine two $or statements

Tags:

mongodb

I am trying to perform a query which is composed of two $or's:

|--------------------
| Date1  |  Date2   |
|--------------------
| NULL   |  NULL    | *
| NULL   |  TODAY   | *
| NULL   |  TOMRW   | 
| TODAY  |  TODAY   | *
| TODAY  |  NULL    | *
| TOMRW  |  NULL    | 
|--------------------

(I've marked the rows that would match with an asterisk)

(Date1 == null || Date1 <= today) && (Date2 == null || Date2 <= today)

I am not sure how to express this query in MongoDB.

It can be broken down into two individual queries that do exactly what they should:

{
    "$or": [{
        "Date1": {
            "$exists": false
        }
    },
    {
        "Date1": {
            "$exists": true,
            "$lte": new Date("2012-01-07T04:45:52.057Z")
        }
    }]
}

and

{
    "$or": [{
        "Date2": {
            "$exists": false
        }
    },
    {
        "Date2": {
            "$exists": true,
            "$lte": new Date("2012-01-07T04:45:52.057Z")
        }
    }]
}

Both of these select the correct set of documents - I just dont know how to execute them as a single query.

My initial thought was to do a query like this:

{
    $and: [orQuery1, orQuery2]
}

Using an $and query returns 0 results. It was explained why here in this thread: $and query returns no result

Also in that thread, a suggestion was made to do a query like this:

{
    Key: {valToMatch1: 1, valToMatch2: 2}
}

But I dont think an $or can be executed this way.

So, the question is: How do I construct my query such that I can combine the two $or's into a single query?

(Its getting very late so I hope this question makes sense.)

like image 335
Bryan Migliorisi Avatar asked Jan 07 '12 05:01

Bryan Migliorisi


People also ask

Can I combine 2 IF statements in Excel?

It is possible to nest multiple IF functions within one Excel formula. You can nest up to 7 IF functions to create a complex IF THEN ELSE statement. TIP: If you have Excel 2016, try the new IFS function instead of nesting multiple IF functions.

How do you do multiple ifs statements?

To use multiple IF functions where we can add multiple logical tests, after the first logical condition and TRUE value, again insert another IF Function followed by the different logical values to be compared with the TRUE value result.

Can you add IF statements together?

In case you need to evaluate a few sets of different conditions, you can express those conditions using OR as well as AND function, nest the functions inside IF statements, and then nest the IF statements into each other.

Can you put two IF statements one after the other?

A nested if statement is an if statement placed inside another if statement. Nested if statements are often used when you must test a combination of conditions before deciding on the proper action.


1 Answers

use test
db.test.insert({a:1})
db.test.insert({a:2, Date2:new Date("01/07/2012")})
db.test.insert({a:3, Date2:new Date("01/08/2012")})
db.test.insert({a:4, Date1:new Date("01/07/2012"), Date2:new Date("01/07/2012")})
db.test.insert({a:5, Date1:new Date("01/07/2012")})
db.test.insert({a:6, Date1:new Date("01/08/2012")})

first subquery db.test.distinct('a', {...});

[1, 2, 3]

second subquery db.test.distinct('a', {...});

[ 1, 5, 6 ]

(Date1 == null || Date1 <= today) && (Date2 == null || Date2 <= today)

unwind

Date1 == null && Date2 == null ||
Date1 == null && Date2 <= today ||
Date1 <= today && Date2 == null ||
Date1 <= today && Date2 <= today ||

query

db.test.find(
{
  $or : 
  [
    {$and: [
        {"Date1": {"$exists": false}},
        {"Date2": {"$exists": false}}
      ]},
    {$and: [
        {"Date1": {"$exists": false}},
        {"Date2": {
            "$exists": true,
            "$lte": new Date("2012-01-07T04:45:52.057Z")}
        }
      ]},
    {$and: [
        {"Date2": {"$exists": false}},
        {"Date1": {
            "$exists": true,
            "$lte": new Date("2012-01-07T04:45:52.057Z")}
        }
      ]},
    {$and: [
        {"Date2": {
            "$exists": true,
            "$lte": new Date("2012-01-07T04:45:52.057Z")}
        },
        {"Date1": {
            "$exists": true,
            "$lte": new Date("2012-01-07T04:45:52.057Z")}
        }
      ]}
  ]
})
>[ 1 ]

this should work too (assume that 'not exist' and 'null' is the same)

db.test.find(
{
  $and : 
  [
    {$or: [
        {"Date1": null},
        {"Date1": { "$lte": new Date("2012-01-07T04:45:52.057Z")} }
      ]},
    {$or: [
        {"Date2": null},
        {"Date2": { "$lte": new Date("2012-01-07T04:45:52.057Z")} }
      ]}
  ]
}
)
like image 157
Radik Avatar answered Nov 04 '22 09:11

Radik