Searching CMS Objects

You can search for CMS objects using JavaScript by means of the following function:

Copy
scrivito.obj_where(field, operator, value, boost=undefined)

The parameters are similar to those of the BasicObj.where ruby method. The function returns a chainable search query object for which the following chainable functions are available:

Copy
// Add more conditions to the query
and(field, operator, value, boost=undefined)
and_not(field, operator, value)

// Omit the first n results
offset(n)

// Order the results
order(field).

// Order results, explicitly specifying
// the sort direction, 'asc'ending or 'desc'ending.
order({field: 'desc'}).

// Reverse a previouly defined order (deprecated)
reverse_order().

// Specify how many results to fetch per request
batch_size(20)

To actually retrieve the search results, call the following function of a query object:

Copy
load_batch() --> Promise(result, next)

The function returns a Promise. The Promise resolves to the result and next parameters.

result is an object that has two keys, total and hits: total is a number representing the total number of available search hits. hits is an array containing the actual search hits, the IDs of the CMS objects:

Copy
{
  total: 12,
  hits: ['5f388ca7ce789341', '35dbf72fec784108']
}

Note that load_batch retrieves at most batch_size items. It may also return fewer items, even if the search is not yet exhausted. This happens, for example, if the request exceeds the rate limit.

If the search is exhausted (i.e. all search hits have been retrieved), next is undefined. Otherwise, next is another chainable search query object whose offset specifies the number of hits that can be skipped since they have already been retrieved.

Example usage:

Copy
scrivito.obj_where("_obj_class", "equals", "Publication").
  and_not("_path", "starts_with", "/about_us").
  offset(70).
  order({title: 'desc'}).
  batch_size(20).
  load_batch().then(function(result, next) {
    console.debug("the first " + result.hits.length + " of " + result.total + " results:");
    _.each(result.hits, function(obj_id) {
      console.debug(obj_id);
    });


    if (!next) {
      console.debug("that's all there is.");
    } else {
      next.load_batch().then(function(result, next) {
        console.debug("the second batch of results:");


        _.each(result.hits, function(obj_id) {
          console.debug(obj_id);
        });
      });
    }
  });

You may also use size instead of load_batch if you are merely interested in the total number of hits:

Copy
scrivito.obj_where("_obj_class", "equals", "Publication").size().then(function(total) {
  console.debug("Total number of hits: " + total);
});

The search query object provides a chainable method, format, for specifying the formatter to be used. If a formatter is given, the hits returned are formatted accordingly.

The formatter needs to be defined in your application. The recommended location is config/initializers/scrivito.rb:

Copy
Scrivito::Configuration.register_obj_format('simple_obj') do |obj|
  {
    id: obj.id,
    title: obj.title.capitalize,
    path: obj.path
  }
end

A search example in which the formatter above is used:

Copy
scrivito.obj_where(...).format("simple_obj").load_batch().then(function(result, next) {
  _.each(result.hits, function(hit) {
    console.debug("Id: " + hit.id);
    console.debug("Title: " + hit.title);
    console.debug("Path: " + hit.path);
  });
});

If no formatter is specified, only the IDs of the CMS objects are returned.