Brightspot CMS Developer Guide

Predicates


The Query API includes several methods to filter search results based on specified conditions, such as where, and, or, and not. Conditions are expressed with compound, comparison, and other predicates, as described below:

Basic comparisons

Basic Comparisons
=, eq The left-hand expression is equal to the right-hand expression.
>=, => The left-hand expression is greater than or equal to the right-hand expression.
<=, =< The left-hand expression is less than or equal to the right-hand expression.
> The left-hand expression is greater than the right-hand expression.
< The left-hand expression is less than the right-hand expression.
!=, <> The left-hand expression is not equal to the right-hand expression.
Boolean predicates
true A predicate that always evaluates to TRUE.
false
A predicate that always evaluates to FALSE.
Basic compound predicates
AND, && Logical AND.
OR, || Logical OR.
NOT Logical NOT.
String comparisons
startsWith The value of the field specified in the left-hand expression begins with the right-hand expression.
matches The left-hand expression matches right-hand expression using a full-text search.
contains The left-hand expression partially or completely matches right-hand expression.
  • Use contains on short text fields such as a name or title.
  • Use matches for large bodies of text.
Other predicates
missing The left-hand expression is missing.

Predicates are used for testing field values. Fields evaluated with predicate operations must be annotated with @Recordable.Indexed.

The where method is the most common Query method for testing field values. For example, the following query uses a comparison operator = to return all Activity instances with an activityType field value equal to checkin.

Query<Activity> query = Query.from(Activity.class);
query.where("activityType = 'checkin'");
List<Activity> activities = query.selectAll();

You can include logical operations in the where method.

Query<Activity> query = Query.from(Activity.class);
query.where("activityType = 'checkin' or activityType = 'cancel'");
List<Activity> activities = query.selectAll();

Logical operations can also be expressed with Query compound clauses.

Query<Activity> query = Query.from(Activity.class);
query.where("activityType = 'checkin'");
query.or("activityType = 'cancel'");
List<Activity> activities = query.selectAll();

In the above examples, the Query object returned from the from method is used for all subsequent methods called on the object. As an alternative to creating a separate statement for each Query method, you can chain the methods in one statement.

List<Activity> activities = Query.from(Activity.class)
                            .where("activityType = 'checkin'")
                            .or("activityType = 'cancel'")
                            .selectAll();


Predicates can be expressed as strings or objects. In the previous examples, strings are used in various Query methods. However, there are versions of these methods that take a Predicate object to express logical and comparison operations.

The following examples contrast two versions of Query methods that take predicate arguments. The first example retrieves an activity log for a given date, project, and user except for the activity logon.

Constructing a compound predicate with methods

String name = "aHoward"; 
String projCode = "evans-26-b825";
User user = Query.from(User.class).where("userName = ?", name).first(); 
Project project = Query.from(Project.class).where("code = ?", projCode).first();

Date date = new SimpleDateFormat("MM/dd/yyyy").parse("03/27/2017"); 

Query<Activity> query = Query.from(Activity.class); 

query.where("activityUser = ?", user); 
query.and("activityDate = ?", date);
query.and("project = ?", project);
query.not("activityType = ?", "logon");
return query.selectAll();
  • Initializes username and project code.
  • Retrieves corresponding User and Project records.
  • Instantiates required Date record.
  • Instantiates a Query object for retrieving activities.
  • Builds a compound predicate from the previously retrieved objects using the and and not methods.
  • Executes query.

The following example executes the same query using the Predicate class.

String name = "aHoward"; 
String projCode = "evans-26-b825";
Query<Activity> query = Query.from(Activity.class);
      
String opEqualsAny = PredicateParser.EQUALS_ANY_OPERATOR; 
String opAnd = PredicateParser.AND_OPERATOR;
String opNotEqualsAll = PredicateParser.NOT_EQUALS_ALL_OPERATOR;

Predicate predicate = new ComparisonPredicate(opEqualsAny, true, "activityUser", Arrays.asList(user)); 

predicate = new CompoundPredicate(opAnd, 
                Arrays.asList(predicate,
                               new ComparisonPredicate(comparisonEqualsAny, true, "activityDate", Arrays.asList(date))));

predicate = new CompoundPredicate(opAnd, 
                 Arrays.asList(predicate,
                               new ComparisonPredicate(comparisonOp, true, "project", Arrays.asList(project))));

predicate = new CompoundPredicate(opNotEqualsAll, 
                 Arrays.asList(predicate,
                               new ComparisonPredicate(comparisonOp, true, "activityType", Arrays.asList("logon"))));

return query.where(predicate).selectAll();
  • Search variables as defined in the snippet Constructing a compound predicate with methods above.

  • Initializes comparison and compound operators. See PredicateParser for the complete list of compound operators.
  • Creates a ComparisonPredicate object that filters activity objects by the specified user.
  • Creates a CompoundPredicate object that filters activity objects by the specified date.
  • Creates a CompoundPredicate object that filters activity objects by the specified project.
  • Creates a CompoundPredicate object from a list of the previous CompoundPredicate objects and excludes instances of activity type logon.
  • Executes query.


The PredicateParser class includes EQUALS_ANY_OPERATOR. This operator uses OR logic, where foo = [ a, b, c ] translates to foo = a OR foo = b OR foo = c.

Consider an Article type with a categories list field, used to enter subject categories. You could use the PredicateParser.EQUALS_ANY_OPERATOR to find articles in the categories environment, nature, or politics.

Predicate predicate = new ComparisonPredicate(PredicateParser.EQUALS_ANY_OPERATOR, true, "category", Arrays.asList("environment","nature","politics"));

However, to find articles with all of the category values of “environment” and “nature” and “politics”, you would need to apply “equalsall” logic. This operator uses AND logic, where foo = [ a, b, c ] translates to foo = a AND foo = b AND foo = c.

Because PredicateParser does not include an “equalsall” operator, you need to build a query that tests for the inclusion of each value in a list field. For example, the following for loop would build a query to find articles categorized with “environment” and “nature” and “politics."

ArrayList<String> subjects = new ArrayList<String>();
subjects.add("environment");
subjects.add("nature");
subjects.add("politics");

for (String subject : subjects) {
    query.and("categories = ?", subject);
}


The PredicateParser class includes NOT_EQUALS_ALL_OPERATOR. This operator uses AND logic, where foo != [ a, b, c ] translates to foo != a AND foo != b AND foo != c.

Consider an Article type with a categories list field, used to enter subject categories. You could use the PredicateParser.NOT_EQUALS_ALL_OPERATOR to find articles not included in the categories environment, nature, and politics.

Predicate predicate = new ComparisonPredicate(PredicateParser.NOT_EQUALS_ALL_OPERATOR, true, "category", Arrays.asList("environment","nature","politics"));

However, to find articles with none of the category values of “environment” or “nature” or “politics”, you would need to apply “notequalsany” logic. This operator uses OR logic, where foo != [ a, b, c ] translates to foo != a OR foo != b OR foo != c.

Because PredicateParser does not include a “notequalsany” operator, you need to build a query that tests for the exclusion of each value in a list field. For example, the following for loop would build a query to find articles that are not categorized with “environment” or “nature” or “politics.”

ArrayList<String> subjects = new ArrayList<String>();
subjects.add("environment");
subjects.add("nature");
subjects.add("politics");

for (String subject : subjects) {
    query.and("categories != ?", subject);
}

Previous Topic
FROM
Next Topic
Paginated results
Was this topic helpful?
Thanks for your feedback.
The elements that get you up and running in a matter of days, from pre-built content types, to modules, to landing pages.

Content types
Modules
Landing pages
Everything you need to manage and administer content within Brightspot CMS, including plug-and-play integrations.

Dashboards
Authoring content
Workflows
Admin configurations
A guide for installing, supporting and administering code on the Brightspot platform, including integrations requiring developer support to use.

Field types
Content modeling
Rich-text elements
Images