If you use ColdBox’s awesome CriteriaBuilder at all, you know it’s dead simple to create complex AND dynamic criteria queries. If you’re like me, a lot of your criteria queries are a bunch of “and”s built together. For example, let’s imagine we’re trying to get all the cars from our database that have a make of Ford and a color of Red. A simple criteria query for this might look like:

// create criteria
var c = newCriteria();
    // add criteria
    c.isEq( "Make", "Ford" )
     .isEq( "Color", "Red" );
// get result
var result = c.list();

Pretty simple, right?

Of course, not all queries are “and“s. Sometimes, you need to do an “or“. Perhaps we want to get all the cars that are Ford OR Red. Again, this is very easy with CriteriaBuilder:

// create criteria
var c = newCriteria();
    // add criteria
    c.or( 
        c.restrictions.isEq( "Make", "Ford" ), 
        c.restrictions.isEq( "Color", "Red" ) 
    );
// get result
var result = c.list();

While this works, it’s not complete. Sure, there are some scenarios where you will know ahead of time what criteria you want to use in a criteria query. However, consider a scenario in which you have a search form in which a user can select from a list of “selectors” to include as a part of their search. In this case, using “or()” won’t work very well, since we would need to dynamically build the restrictions that are added to the criteria query.

Fortunately, CriteriaBuilder makes this super easy to accomodate with the disjunction() criteria. The disjunction() criteria is quite simple to use. It takes one argument: an array of restrictions. Because it accepts an array, we can easily build the array contents dynamically, and then pass the array to the disjunction:

// array of filters from search form
...
filters = [
    { property="Make", value="Ford" },
    { property="Model", value="Escort" },
    { property="Color", value="Red" }
];
...
// create criteria
var c = newCriteria();
// array of restrictions
var theOrs = [];
// loop over filters
for( var filter in filters ) {
    // add to array
    arrayAppend( 
        theOrs,
        c.restrictions.isEq( filter.property, filter.value )
    );
}
// array of "or"s as disjunction()
c.disjunction( theOrs );
// get the result
var result = c.list();

By using the disjunction, CriteriaBuilder will group together the criterias into a single disjunction, giving us a “WHERE” clause in the executed SQL like:

...
WHERE ( Make='Ford' OR Model='Escort' OR Color='Red )
...

And of course, since the expressions are grouped, you can continue using CriteriaBuilder to add additional criteria, just like you normally would.