Query Mapping
This section describes how SQL statements are interpreted and translated into Elasticsearch queries. Examples are also provided to explain the behavior of various queries.
Query/Filter Context and Scoring
When the _score column is selected, scoring will be requested by issuing a query context request, which scores the quality of the search results. By default, results are returned in descending order based on the calculated _score. An ORDER BY clause can be specified to change the order of the returned results.When the _score column is not selected, a filter context will be sent, in which case Elasticsearch will not compute scores. The results for these queries will be returned in arbitrary order unless an ORDER BY clause is explicitly specified.
Text Matching and Search
Analyzed fields in Elasticsearch are stored in an inverted index after they are run through an analyzer. Analyzers are customizable and thus can perform a variety of different filters on the data prior to storing them in the inverted index. For example, the default Elasticsearch analyzer will lowercase all the terms.To demonstrate this point, an
analyzed field in Elasticsearch was created with a value of 'Bike'. After being analyzed, the value will be stored in the inverted index (using the default analyzer) as 'bike'.
A non-analyzed field, on the other hand, would not analyze the search value and thus would be stored as 'Bike'.
When performing searches, some Elasticsearch query types run the search value through an analyzer (which will make the search case insensitive) and some do not (making the search
case sensitive). Additionally, the default analyzer breaks up fields containing multiple words into separate terms. When performing searches on these fields,
Elasticsearch may return records that contain the same words but in a different order. For example, a search is performed using a value of 'blue sky' but a record with
'sky blue' is returned.
To work around these case-sensitivity and ordering issues, the CData JDBC Driver for Elasticsearch will identify the column as analyzed or non-analyzed and will issue the appropriate Elasticsearch query based on the specified operator (such as =) and the search value.
Equals and Not Equals
Where clauses that contain an equals (=) or not equals (!= or <>) filter issue different Elasticsearch queries depending upon the column and data used. Analyzed and non-analyzed columns behave differently and thus different Elasticsearch queries are generated to provide the best search functionality. Additionally, string values generate different query types depending upon whether they contain empty space or not. Below is an explanation of the rules and behavior for the varying cases.Analyzed Columns
Analyzed columns are stored after being run through an analyzer. As a result of that, the search values specified will be run through an analyzer on the Elasticsearch server prior to the search.
This makes the searches case-insensitive (provided the analyzer used handles casing).
WHERE Clause Examples | Elasticsearch Query Type |
WHERE analyzed_column='value' | Query String Query |
WHERE analyzed_column='value with spaces' | Match Phrase Query |
Non-Analyzed Columns
Non-analyzed columns are stored without being run through an analyzer. Thus, non-analyzed columns are case sensitive and thus search values specified for these columns are case sensitive. If the search value is
a single word, the driver will check the filter with the original casing specified along with three common forms: uppercase, lowercase, and capitalized. If the search value
contains multiple words, the search value will be sent as-is and thus is case sensitive.
WHERE Clause Examples | Elasticsearch Query Type |
WHERE nonanalyzed_column='myValue' | Query String Query: Four cases are checked - myValue OR MYVALUE OR myvalue OR Myvalue |
WHERE nonanalyzed_column='value with spaces' | Wildcard Query |
IN and NOT IN
The IN and NOT IN operators function very similarly to the equals and not equals operators.WHERE Clause Examples | Behavior |
WHERE column IN ('value') | Treated as: column='value' |
WHERE column NOT IN ('value') | Treated as: column!='value' |
WHERE column IN ('value1', 'value2') | Treated as: column='value1' OR column='value2' |
WHERE column NOT IN ('value1', 'value2') | Treated as: column!='value1' AND column!='value2' |
LIKE and NOT LIKE
The LIKE and NOT LIKE operators allow the use of wildcard characters. The percent sign (%) represents zero, one, or multiple characters. The underscore (_) represents a single character (in which the character must be present).WHERE Clause Examples | Behavior |
WHERE column LIKE 'value' | Treated as: column='value' |
WHERE column NOT LIKE 'value' | Treated as: column!='value' |
WHERE analyzed_column LIKE 'v_lu%' | Query String Query with wildcards |
WHERE nonanalyzed_column LIKE 'v_lu%' | Wildcard Query with wildcards |
Aggregate Filtering
Aggregate data may consist of JSON objects or arrays (both primitive and object arrays).JSON objects and arrays of objects will be treated as raw strings and all filtering will be performed by the driver. Therefore an equals operation must match the entire JSON aggregate to return a result, unless a CONTAINS or LIKE operation is used.
If JSON objects are flattened into individual columns (via FlattenObjects and FlattenArrays), the column for the specific JSON field will be treated as individual columns. Thus the data type will be that as contained in the Elasticsearch mapping and all filters will be pushed to the server (where applicable).
JSON primitive array aggregates will also be treated as raw strings by default and filters will be performed by the driver. To filter data based on whether a primitive array contains a single value, the INARRAY function can be used (e.g. INARRAY(column) = 'value'). When performing a search on array fields, Elasticsearch looks at each value individually within an array. Thus when the INARRAY function is specified in a WHERE clause, the filter will be pushed to the server which performs a search within an array.
Primitive arrays may consist of different data types, such as strings or ints. Therefore the INARRAY function supports comparison operators applicable to the data type within the Elasticsearch mapping for the field. For example, INARRAY(int_array) > 5, will return all rows of data in which the int_array contains a value greater than 5. Supported comparison operators include the use of the LIKE operator for string arrays.