I have a class named Event
, it has a column named end_time
of type Date and a column named title
of type String. I would like to fetch the events whose end_time
column is either undefined or is greater than or equal to new Date()
. This is not difficult as it can be done with the following code:
var query1 = new Parse.Query(Event);
var query2 = new Parse.Query(Event);
query1.doesNotExist("end_time");
query2.greaterThanOrEqualTo("end_time", new Date());
var query1And2 = Parse.Query.or(query1, query2);
query1And2
can correctly return the results I want. However, the problem is if I add one more constrain like: given a user specified title, return the events whose title is either undefined or equals user specified title. This constrain is not difficult to construct in its own, like:
var query3 = new Parse.Query(Event);
var query4 = new Parse.Query(Event);
query3.doesNotExist("title");
query4.equalTo("title", userTitle);
var query3And4 = Parse.Query.or(query3, query4);
but, how can I query Event
with both query1And2
and query3And4
?
These constraints can be achieved with a little boolean math. It looks like you already understand that parse allows you to specify conjunctive (and) constraints on a single query and disjunctive (or) constraints by combining multiple queries with Query.or()
**. So to get the constraints you're aiming for, we need to transform your query logic to disjucntive form.
Your individual predicates are:
A = doesNotExist("end_time")
B = greaterThanOrEqualTo("end_time", new Date())
C = doesNotExist("title")
D = equalTo("title", userTitle)
and we wish to produce the query:
(A or B) and (C or D)
Rewriting this product of sums as a sum of products using algebra, we get:
= (A and C) or (B and C) or (A and D) or (B and D)
= q0 or q1 or q2 or q3
where q0..q3 are queries constrained by ANDed constraints. Rendering those as code:
var q0 = new Parse.Query(Event);
q0.doesNotExist("end_time");
q0.doesNotExist("title");
var q1 = new Parse.Query(Event);
q1.greaterThanOrEqualTo("end_time", new Date());
q1.doesNotExist("title");
var q2 = new Parse.Query(Event);
q2.doesNotExist("end_time");
q2.equalTo("title", userTitle);
var q3 = new Parse.Query(Event);
q3.greaterThanOrEqualTo("end_time", new Date());
q3.equalTo("title", userTitle);
var querySum = Parse.Query.or(q0, q1, q2, q3);
** Query.or() probably just runs those queries separately they way we would with Promise.when() and combines the results, but lets assume that parse does a better job at this than we can at the app level.