I have a set of conditions on my node app where I am trying to implement the following if block -
if(((public==true)&&(varA=="something" || varB == "something")) || (public==false)&&(varA=="something" || varB == "something")&&(varc == "something"))
so what I tried to implement was something is -
db.foo.find({"$or":[{"$and":[{e:true},{"$or":[{d:"four"},{c:"seven"}]}]},{"$and":[{e:false},{a:"one"},{"$or":[{c:"three"},{c:"seven"}]}]}]})
Now, the variables varA,varB,varC are dynamic so they depend on the user's requests. so I can't write the query object as it is. I will have to write it in an array fashion
( like obj["$or][0]["$and"][e] = true; )
or something along these lines.
can I simplify my query more here ? or is there is a better and more efficient way of getting this required collection.
First, let's examine your boolean condition. It helps to write it out on multiple lines using indentation. Writing it on one line makes it nigh incomprehensible.
(public==true && (varA=="something" || varB == "something"))
||
(public==false)
&&
(varA=="something" || varB == "something")
&&
(varc == "something")
Let's simplify this. Let P be public==true and let A, B, C be the obvious conditions. I'm not sure if all the "something"'s are meant to be all different values or all the same or what, so I'm going to assume that for a fixed value of *, var* conditions use the same "something". Then the condition is
(P && (A || B))
||
~P
&&
(A || B)
&&
C
This is a bit goofy so let's try to simplify further. The easiest way to do this is to use the symbol + for or || and * for and && since the rules for boolean algebra work like the rules for + and * in this way. Not is ~. I'll start using juxtaposition for *, too.
(P * (A + B)) + ~P * (A + B) * C =
PA + PB + (~P)AC + (~P)BC =
A(P + (~P)C) + B(P + (~P)C)
OK. Let's think about this condition. Clearly, we need one of A and B to be true. Then we need P + (~P)C to be true. It's pointless to check ~P in the condition, since if P is true we win, else we need C, so we can simplify the condition to
A(P + C) + B(P + C)
As a query object this looks like
{
"$or" : [
{
varA : "something",
"$or" : [
{ "public" : true },
{ varC : "something" }
]
},
{
varB : "something",
"$or" : [
{ "public" : true },
{ varC : "something" }
]
},
]
}
I would create this object in Javascript as follows:
var myQuery = {
"$or" : [
{
"$or" : [
{ "public" : true },
{ }
]
},
{
"$or" : [
{ "public" : true },
{ }
]
},
]
};
myQuery["$or"][0][varA] = "something";
myQuery["$or"][1][varB] = "something";
myQuery["$or"][0]["$or"][1][varC] = "something";
myQuery["$or"][1]["$or"][1][varC] = "something";
I'd appreciate if you and any other generous SO readers would check over this, as obviously there have been many opportunities for errors in the reasoning and symbolic manipulation.