Variables

When you call a generated method (originated by a template), you can pass a list of hashes of variables that will be interpolated into the templates.

Notice: We will use just one hash in the following examples, but you can actually pass a list of hashes that will be deep merged into one single hash (see Single Call Level).

For example:

my_search:
- query:
    term:
      color: <<the_color>>
MyClass.my_search :the_color => 'blue'

You know that you can also set a tag default (see Tags):

my_search:
- query:
    term:
      color: <<the_color= blue >>
MyClass.my_search

but you can also set a default for all the the_color tags in the source file, or for all the source files used by your class, or for all the requests of your app, etc. by setting them at different levels.

Variable Levels

Elastics allows you to set interpolation variables at different levels, affecting different ranges of requests. They act as sort of cascading defaults, so you can minimize the code needed to set the right value, which is somehow similar to what you do with CSSs.

That is internally achieved by deep-merging all the Elastics::Variables objects in the cascading hierarchy of levels, from the most general to the most specific. More specific variable levels override more general levels.

Here they are, from the most general to the most specific:

1. Configuration Level

Variables set at configuration level will set the default for all the requests of your application and can be overridden by all the other levels. You usually set them by merging or deep-merging your values into the Elastics::Variables object contained in Elastics::Configuration.variables so preserving the values already there:

config.variables.deep_merge! :the_color => 'green'

(see Configuration)

2. Template Class level

This is mostly used internally by the Elastics::Template::* subclasses. You might need it if you want to create a custom template class. In that case take a look at the implementation of elastics/template/slim_search.

class MyTemplateClass < Elastics::Template
  def self.variables
    super.deep_merge(:the_color => 'blue')
  end
  ...
end

3. Host Class level (your class)

When you want to set a default variable for all the requests from your own class (context class) you can simply add the variables to the elastics class proxy of your class:

class MyClass
  include Elastics::Templates
  elastics.variables.deep_merge!(:the_color => 'red')
  elastics.load_source :my_source
  ...
end

4. Source Level

When you want to set a default variable for all the requests generated by the same source file you can do so in the loading statement:

elastics.load_source :my_source, :the_color => 'black'

(see Template Sources)

5. Instance Template Level

This level is specially useful when you want to set a variable at the template level (i.e. affecting all the requests made with that template), but you cannot use tag defaults because that tag is not explicit in your template. This is usually the case of the tags used in the path, such as :index, :type or (query) :params that are not accessible from Search Templates. In the following template, the second argument is used as template variables. In this case we want to use the car and truck default types when we use that template.

my_search:
- query:
    term:
      color: <<the_color>>
- type:
  - car
  - truck

6. Tag Level

This is a quite specific level: may be overridden only by the call argument below.

- <<the_color= yellow >>

7. Single Call Level

This is the most specific level where you can set a variable, indeed it affects only that single request and overrides any other level that may set :the_color.

MyClass.my_search :the_color => 'white'

Besides, all the methods that accept a variable hash, can accept a list of hashes as well. The list will be deep-merged and the resulting hash will be used as the final variable hash passed as the arguments. For example:

MyClass.my_search @default_controller_vars, params, :the_color => 'pink'

The order is important: in this case we pass 3 hashes: the 3rd hash will override the 2nd, which will override the 1st.

Special Variables

Variables are usually created by you: their primary function is supplying the values to replace the tags, but there are a few variables that are special because they have a different function, so you cannot define a tag with their name. They are mostly set and used internally, but you might need to pass it explicitly in some special case.

:context

This variable contain the context class, which is usually the class where you included some Elastics module (like Elastics::Templates, Elastics::Scopes, Elastics::ModelIndexer, etc.). It is used by the elastics-scopes gem.

:path

This variable contain the full path of the request. It is usually set and used internally.

:data

This variable contain the data, i.e. the request body (a ruby structure that express the elasticsearch JSON query). You may need to set it directly in some very special case, but it is mostly used internally.

:params

The params are a hash of key/value pairs. Elastics will transform them in the query string part of the path (all what comes after the ?), so you will probably use it quite often.

:no_pruning

Skips the automatic pruning for the keys listed here. You can skip arbitrary keys that are expected to containing nil/empty values (see Pruning)

:raise

Boolean. false will not raise errors coming from elasticsearch.

:raw_result

Boolean. true will return the raw result as returned by elasticsearch. It is mostly useful to skip the automatic casting provided by the Elastics::ActiveModel module, or skip your own post processing of the result (see elasticsresult).

Predefined Variables

Elastics defines a few tags internally, so it adds some predefined variable to the set. For example, when you use Search Templates, you have more predefined variables:

:index

The index or indices. You can set it as a string or as an Array of strings.

:type

The type or types. You can set it as a string or as an Array of strings.

:page

The page number of the pagination. By setting this variable you get automatically set the :from param, consistently with the :size (that is usually defaulted). Very convenient when you get the page number from a pagination link). Default 1.

:cleanable_query

This variable is used to pass querystring queries and it is treated in a special way by Elastics. For example: if you pass a search field content from a web form directly to a querystring query, you may easily get some nasty error by elasticsearch. Indeed there are a few special characters that can break the Lucene syntax, so they should either be escaped/removed or used in a proper way. If you pass the querystring as the `:cleanablequery` variable, Elastics tries to search with its content as is first (so allowing your power users to use advanced queries). But if it gets an error from elasticsearch, then it removes the offending characters from the string, and performs a second search with the cleaned string, and finally returns the result.

See Lucene Query Parser Syntax

my_template:
  query:
    query_string:
      query: <<cleanable_query= '*' >>

# or
my_other_template:
  query:
    query_string:
      # must wrap in quotes or the ':' would generate a YAML error
      "<<cleanable_query= {query: '*'} >>"

MyClass.my_template(:cleanable_query => params[:q])
MyClass.my_other_template( :cleanable_query => { :query  => params[:q],
                                                 :fields => ['text', 'category'] } )
:now

The time at the moment of the execution in milliseconds. It is not set as a real key in the variables hash, but if you use it in any template, it will return the value. If you set it as a regular variable, it will work as any other variable.

When you use other API methods (e.g. Elastics.multi_get, Elastics.stats, …), you may need to set other variables as well (see API Methods). As usual you can get the variables and an usage example in the console with Elastics.doc

Elastics Variables Structure

When you pass a variable hash (or list of hashes) to any elastics method, elastics will create an internal Elastics::Variables instance, which is a special Hash instance.