Advanced Querying¶
OData defines some query options that allows refining the requests:
$filter
$select
$orderby
$expand
Selection: $filter¶
A URI with a $filter
system query option identifies a subset of the entries
from the collection that satisfy the $filter
predicate expression.
Expressions can reference properties and literals. The latter can be strings
(enclosed in single quotes), the null
literal, numbers or boolean values.
The service supports the following operations and functions:
Operators¶
Operator |
Description |
Example |
---|---|---|
eq |
Equal |
|
ne |
Not equal |
|
gt |
Greater than |
|
ge |
Greater than or equal |
|
lt |
Less than |
|
le |
Less than or equal |
|
in |
Is a member of |
|
and |
Logical and |
|
or |
Logical or |
|
not |
Logical negation |
|
add |
Addition |
|
sub |
Subtraction |
|
mul |
Multiplication |
|
div |
Division |
|
mod |
Modulo |
|
() |
Precedence grouping |
|
String Functions¶
The following functions are available for strings operations:
contains(string p0, string p1)
returnstrue
when the value of the property name specified inp0
contains the stringp1
. Otherwise returnsfalse
.startswith(string p0, string p1)
returnstrue
when the value of the property name specified inp0
starts with the stringp1
. Otherwise returnsfalse
.endswith(string p0, string p1)
returnstrue
when the value of the property name specified inp0
ends with the stringp1
. Otherwise returnsfalse
.indexof(string p0, string p1)
returns the position of the stringp1
in the value of the property name specified inp0
.length(p0)
returns the length of the value of the property name specified inp0
.substring(string p0, int pos)
returns a new string that is a substring of the value of the property name specified inp0
. The substring begins with the character at the specifiedpos
and extends to the end of this string.substring(string p0, int pos, int length)
returns a new string that is a substring of the value of the property name specified inp0
. The substring begins at the specifiedpos
and extends to the character at indexpos
+length
.tolower(string p0)
returns a copy of the value of the property name specified inp0
converted to lowercase.toupper(string p0)
returns a copy of the value of the property name specified inp0
converted to uppercase.trim(string p0)
returns a copy of the value of the property name specified inp0
with leading and trailing whitespace omitted.concat(string p0, string p1)
returns a new string that is a concatenation of the stringp0
and the stringp1
.
The following table shows a summary and examples of these functions:
Function |
Example |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Math Functions¶
There are three math functions: round
, floor
, ceiling
. Each one
allows Double
or Decimal
types as parameters and the returned value is
of the same type as the parameter.
Function |
Example |
---|---|
round |
|
floor |
|
ceiling |
|
Date Functions¶
Function |
Example |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Projection: $select¶
The $select
system query option returns only the properties explicitly
requested. $select
expression can be a comma-separated lists of properties
or the star operator (*
), which will retrieve all the properties.
Example:
/denodo-odata.svc/movies/actor?$select=actor_id,first_name,last_name
Response:
{
"@odata.context":"/denodo-odata.svc/movies/$metadata#actor(actor_id,first_name,last_name)",
"value": [
{
"actor_id": 1,
"first_name": "PENELOPE",
"last_name": "GUINESS"
},
...
]
}
Another example:
/denodo-odata.svc/movies/actor?$select=*
Response:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#actor(*)",
"value": [
{
"actor_id": 1,
"first_name": "PENELOPE",
"last_name": "GUINESS",
"last_update": "2006-02-15T11:34:33Z"
},
...
]
}
Note
Complex properties can be used in $select
expressions:
denodo-odata.svc/admin/struct_table_film?$select=film_data/title
Response:
{
"@odata.context":"/denodo-odata.svc/admin/$metadata
#struct_table_film(film_data/title)",
"value": [
{
"@odata.id": "/denodo-odata.svc/admin/struct_table_film(1)",
"film_data": {
"title": "ACADEMY DINOSAUR"
}
...
}
...
]
}
Ordering Results: $orderby¶
The $orderby
query parameter specifies the order in which items are
returned:
/denodo-odata.svc/<database name>/collectionName?$orderby=attribute [asc|desc]
To order the collection the resource path must identify a collection of entries, otherwise this option is unavailable.
The keywords asc
and desc
determine the direction of the sort (ascending
or descending, respectively). If asc
or desc
are not specified, items are
returned in ascending order. Null values come before non-null values when
sorting in ascending order and vice versa.
You can also sort by multiple attributes:
/denodo-odata.svc/<database name>/collectionName?$orderby=attribute1 [asc|desc],attribute2 [asc|desc]
Example:
/denodo-odata.svc/movies/address?$orderby=zip,client_identifier desc
Note that, for some RDMBS (such as Oracle), the ordering of null
values is executed just in the opposite way as
defined in the OData specification. This means that OData specification says that null
values must be placed first
in an ASC
ordination, as well as placed last in a DESC
ordination, but some RDBMS do the other way around.
To force the ordination the way the OData specification defines, open the
{<DENODO_HOME>}/resources/apache-tomcat/webapps/denodo-odata4-service/WEB-INF/classes/configuration.properties
file
and set the property forceSpecNullOrdering
to true
.
Parameter Aliases¶
Parameter aliases are identifiers prefixed with an @
sign. They can be used
in query expressions to avoid stating the same literal multiple times, or
deferring lengthy literals to a place where they are easier to read.
Example:
/denodo-odata.svc/movies/film?$filter=contains(title,@p1) and not contains(description,@p1)&@p1='ACADEMY DINOSAUR'
Specifying Maximum Number of Results: $top¶
With the $top
option you can select the n
first entries of the
collection, being n
a non-negative integer:
/denodo-odata.svc/<database name>/collectionName?$top=n
Example:
/denodo-odata.svc/movies/actor?$top=1
Response:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#actor",
"value": [
{
"actor_id": 1,
"first_name": "PENELOPE",
"last_name": "GUINESS",
"last_update": "2006-02-15T11:34:33Z"
}
]
}
Specifying Offset: $skip¶
With the option $skip
, the n
first entries of the collection will not be
shown in the response. n
is a non-negative integer:
denodo-odata.svc/<database name>/collectionName?$skip=n
Example:
/denodo-odata.svc/movies/actor?$skip=199
Response:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#actor",
"value": [
{
"actor_id": 200,
"first_name": "THORA",
"last_name": "TEMPLE",
"last_update": "2006-02-15T11:34:33Z"
}
]
}
Asking for Total Result Count: $count¶
The $count
system query option returns the number of items returned in the
response along with the result.
The old syntax $inlinecount=allpages
has been shortened in OData 4 to
$count=true
.
The $count
system query option ignores $top
, $skip
, and $expand
query options, and returns the total count of results across all pages including
only those results matching any specified $filter
.
Example:
/denodo-odata.svc/movies/actor?$count=true
Response:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#actor",
"@odata.count": 200,
"value": [
{
"actor_id": 1,
"first_name": "PENELOPE",
"last_name": "GUINESS",
"last_update": "2006-02-15T11:34:33Z"
},
...
]
}
Another example:
/denodo-odata.svc/movies/actor?$count=true&$filter=actor_id eq 1
Response:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#actor",
"@odata.count": 1,
"value": [
{
"actor_id": 1,
"first_name": "PENELOPE",
"last_name": "GUINESS",
"last_update": "2006-02-15T11:34:33Z"
}
]
}
Another example:
/denodo-odata.svc/movies/actor?$count=false
Response:
Actor data, just the same as a request without $count
option:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#actor",
"value": [
{
"actor_id": 1,
"first_name": "PENELOPE",
"last_name": "GUINESS",
"last_update": "2006-02-15T11:34:33Z"
},
...
]
}
Lambda Operators: any¶
OData defines operators that evaluate a Boolean expression on a collection called lambda operators
. The argument of a lambda operator is a lambda variable name followed by a colon (:) and a Boolean expression that uses the lambda variable name to refer to properties of the related entities identified by the navigation path.
The any operator applies a boolean expression to each member of a collection and returns true
if the expression is true for any member of the collection, otherwise it returns false
.
/denodo-odata.svc/<DBNAME>/collectionName?$filter=relatedEntity/any(f:f/relatedEntityField <OPERATION> <VALUE>)
/denodo-odata.svc/<DBNAME>/collectionName?$filter=relatedEntity/any(f:f/relatedEntityField <OPERATION> <VALUE>)
Example:
/denodo-odata.svc/country?$filter=city/any(f:f/city_id eq 2)
Response:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#country",
"value": [
{
"country_id": 82,
"country": "Saudi Arabia",
"last_update": "2006-02-15T02:44:00Z"
}
]
}
Another example:
/denodo-odata.svc/country?$filter=country_id eq 87&$expand=city($filter=address_sakila/any(f:f/address_id eq 56))
Response:
{
"@odata.context": "/denodo-odata.svc/movies/$metadata#country(city())",
"value": [
{
"country_id": 87,
"country": "Spain",
"last_update": "2006-02-15T02:44:00Z",
"city": [
{
"city_id": 1,
"city": "A Coruna (La Coruna)",
"country_id": 87,
"last_update": "2006-02-15T02:45:25Z"
}
]
}
]
}
Note that the All
operator is not supported by the Denodo OData Service.
System Query Option: $apply¶
Aggregation behavior is triggered using the $apply query option. It takes a sequence of set transformations, separated by forward slashes to express that they are consecutively applied.
The Denodo OData Service supports the simple grouping feature of the groupby transformation only for the fields defined over the entity that is being queried. Grouping navigational fields is not supported as explained in the Limitations section of this manual.
The Service also supports the aggregate
along with the min
, max
, sum
and average
aggregation
functions.
Both transformations can be used individually or together, as shown in the following examples:
groupby
/denodo-odata.svc/database/film?$apply=groupby((release_year,rating))
Response:
{
"@odata.context": "http://localhost:9090/denodo-odata4-service/denodo-odata.svc/database/$metadata#film(release_year,rating)",
"value": [
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "G"
},
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "PG"
},
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "PG-13"
},
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "R"
},
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "NC-17"
}
]
}
aggregate
/denodo-odata.svc/database/payment?$apply=aggregate(amount with max as max_amount,amount with min as min_amount,amount with average as avg_amount,amount with sum as sum_amount)
Response:
{
"@odata.context": "http://localhost:9090/denodo-odata4-service/denodo-odata.svc/database/$metadata#payment(amount)",
"value": [
{
"@odata.id": null,
"max_amount": 11.99,
"min_amount": 0.00,
"avg_amount": 4.200667,
"sum_amount": 67416.51
}
]
}
groupby
andaggregate
/denodo-odata.svc/database/film?$filter=rental_duration eq 6&$orderby=rating desc&$apply=groupby((release_year,rating),aggregate(length with average as avg_length,rental_duration with average as avg_rental_duration))&$top=4
Response:
{
"@odata.context": "http://localhost:9090/denodo-odata4-service/denodo-odata.svc/database/$metadata#film(release_year,rental_duration,length,rating)",
"value": [
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "R",
"avg_length": 127.1852,
"avg_rental_duration": 6.0
},
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "PG-13",
"avg_length": 118.52,
"avg_rental_duration": 6.0
},
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "PG",
"avg_length": 104.8205,
"avg_rental_duration": 6.0
},
{
"@odata.id": null,
"release_year": "2006-01-01",
"rating": "NC-17",
"avg_length": 111.7895,
"avg_rental_duration": 6.0
}
]
}