Friday 6 March 2015

Using a Search object in an TACTIC Expression

Another interesting feature added to 4.4 is the ability to add use a Search object as starting point for the expression language.  At present this only makes sense for server side code, so this code needs to be used on the "Python" tab on custom widgets or in server side triggers.  On server side code, TACTIC uses the Search object for all searches.  It packages up all search functionality possible in a single object.

The expression language is very convenient for doing relatively complex queries very simply.  Previous, the expression language could use a list of sobjects as a starting point.

For example:

expression = "@SUM(vfx/shot.cost)"
results = Search.eval( expression, sobjects=sobjects)

The sobjects passed in will be used as a "starting" point for the expression and evaluate the expression relative to those starting sobjects.   In this case, it will calculate the total sum of all the "cost" values for all the sobjects.

SObjects are usually built by an Search object such as:

search = Search("vfx/shot")
search.add_filter("sequence_code", "XYZ")
sobjects = search.get_sobjects()

Now if we wanted to use the resultant sobjects in an expression, we would have to do:

results = Search.eval(expression, sobjects=sobjects)

This was inefficient because it would do a search on the database, build all the sobjects and then extract information from those sobjects to operate on.  This made it impossible or inefficient to do further filters on the passed in list.

Passing in a Search object delays the search until the expression language has had a change to add extra filters.  So the above example would change to:

search = Search("vfx/shot")
search.add_filter("sequence_code", "XYZ")
results = Search.eval(expression, search=search)

If the expression contained filters, this would be much more efficient:

expression = "@SUM(vfx/shot['date_due','>','$TODAY']['date_due','<','$TOMORROW'])"

These date filters would be applied at the same time as the sequence code filters.

Since the search object is often accessible from a command or widget, this becomes a very convenient way to further operate on a search.  This is especially useful when calculate aggregate data starting from some previously selected search criteria.  More on that later.