How to Filter AutoREST Results with the q Parameter

Ask an AutoREST collection for only the rows you need, with JSON filters for comparisons, patterns, lists, and sorting.

An AutoREST collection returns all rows by default. To get only some of them, clients pass a filter in the q query parameter, written as JSON: equality, comparisons, LIKE patterns, lists, AND and OR, and sorting. ORDS turns the filter into a WHERE clause, so the database does the work. This guide filters a REST-enabled view of airports and shows what happens with operators ORDS does not know.

Before You Start

You need ORDS installed and running against your database, and a schema to work in. The examples use NIMBUS, the sample schema of a fictional airline, which you can install with the scripts in the setup/nimbus folder of the Oracle Database 26ai code repository on GitHub. The schema comes from Oracle Database 26ai SQL and PL/SQL Book.

ORDS in the examples answers at https://localhost:8443/ords/, and NIMBUS is REST-enabled with the URL alias nimbus. Replace the host and port with your own ORDS address. The curl commands use -k because the test server has a self-signed certificate; leave it out when your certificate is trusted. JSON responses are formatted for reading; ORDS returns them on one line.

Syntax

GET .../object_alias/?q={"column":"value"}
GET .../object_alias/?q={"column":{"$gt":100}}
GET .../object_alias/?q={"$or":[{...},{...}],"$orderby":{"column":"desc"}}

Operators include $eq, $ne, $lt, $lte, $gt, $gte, $like, $instr, $in, $between, $null, $notnull, $and, $or, and $orderby. Encode the JSON in the URL; curl does it with -G and --data-urlencode.

A View to Filter

AIRPORTS_V shows five columns of AIRPORTS and is read-only, so the REST API can never change the table.

Example:

create or replace view airports_v as
select airport_code, city, country_code, elevation_ft, is_hub
from   airports
with read only;

begin
  ords.enable_object(p_enabled        => true,
                     p_schema         => 'NIMBUS',
                     p_object         => 'AIRPORTS_V',
                     p_object_type    => 'VIEW',
                     p_object_alias   => 'airports',
                     p_auto_rest_auth => false);
  commit;
end;
/

Output:

View AIRPORTS_V created.

PL/SQL procedure successfully completed.

Filter by Equality

Example:

curl -k -G https://localhost:8443/ords/nimbus/airports/ \
  --data-urlencode 'q={"country_code":"IN"}'

Output:

{
    "items": [
        {
            "airport_code": "BOM",
            "city": "Mumbai",
            "country_code": "IN",
            "elevation_ft": 39,
            "is_hub": false
        },
        {
            "airport_code": "DEL",
            "city": "Delhi",
            "country_code": "IN",
            "elevation_ft": 777,
            "is_hub": false
        },
        {
            "airport_code": "BLR",
            "city": "Bengaluru",
            "country_code": "IN",
            "elevation_ft": 3002,
            "is_hub": false
        }
    ],
    "hasMore": false,
    "limit": 25,
    "offset": 0,
    "count": 3,
    "links": [
        {
            "rel": "self",
            "href": "https://localhost:8443/ords/nimbus/airports/?q=%7B%22country_code%22:%22IN%22%7D"
        },
        {
            "rel": "describedby",
            "href": "https://localhost:8443/ords/nimbus/metadata-catalog/airports/"
        },
        {
            "rel": "first",
            "href": "https://localhost:8443/ords/nimbus/airports/?q=%7B%22country_code%22:%22IN%22%7D"
        }
    ]
}

The three Indian airports come back, each with its own link, and count is 3.

More Filters

Each request below ran against the same view; the table shows the airports it returned.

qReturns
{"elevation_ft":{"$gt":2000}}GRU, BLR, JNB, NBO, KTM
{"city":{"$like":"S%"}}GRU (São Paulo), SIN, SYD
{"city":{"$instr":"on"}}LHR (London), YYZ (Toronto), HKG (Hong Kong)
{"country_code":{"$in":["AE","GB"]}}DXB, LHR
{"elevation_ft":{"$between":[1000,4000]}}BLR, GRU
{"is_hub":true}DXB

Combine Conditions and Sort

$or takes a list of conditions, and $orderby sorts the result. This request asks for the Japanese airport or any airport at 5,000 feet or more, highest first.

Example:

curl -k -G https://localhost:8443/ords/nimbus/airports/ \
  --data-urlencode 'q={"$or":[{"country_code":"JP"},{"elevation_ft":{"$gte":5000}}],"$orderby":{"elevation_ft":"desc"}}'

Output:

{
    "items": [
        {
            "airport_code": "JNB",
            "city": "Johannesburg",
            "country_code": "ZA",
            "elevation_ft": 5558,
            "is_hub": false
        },
        {
            "airport_code": "NBO",
            "city": "Nairobi",
            "country_code": "KE",
            "elevation_ft": 5327,
            "is_hub": false
        },
        {
            "airport_code": "NRT",
            "city": "Tokyo",
            "country_code": "JP",
            "elevation_ft": 141,
            "is_hub": false
        }
    ],
    "hasMore": false,
    "limit": 25,
    "offset": 0,
    "count": 3,
    "links": [
        {
            "rel": "self",
            "href": "https://localhost:8443/ords/nimbus/airports/?q=%7B%22%24or%22:%5B%7B%22country_code%22:%22JP%22%7D%2C%7B%22elevation_ft%22:%7B%22%24gte%22:5000%7D%7D%5D%2C%22%24orderby%22:%7B%22elevation_ft%22:%22desc%22%7D%7D"
        },
        {
            "rel": "describedby",
            "href": "https://localhost:8443/ords/nimbus/metadata-catalog/airports/"
        },
        {
            "rel": "first",
            "href": "https://localhost:8443/ords/nimbus/airports/?q=%7B%22%24or%22:%5B%7B%22country_code%22:%22JP%22%7D%2C%7B%22elevation_ft%22:%7B%22%24gte%22:5000%7D%7D%5D%2C%22%24orderby%22:%7B%22elevation_ft%22:%22desc%22%7D%7D"
        }
    ]
}

Johannesburg and Nairobi come first by elevation, then Tokyo Narita.

When a Filter Is Wrong

$like compares case-sensitively: {"city":{"$like":"s%"}} with a lowercase s returns no rows. There is no case-insensitive $ilike operator; using one is rejected:

Output (HTTP 400 Bad Request):

{
    "code": "BadRequest",
    "message": "Bad Request",
    "type": "tag:oracle.com,2020:error/BadRequest",
    "instance": "tag:oracle.com,2020:ecid/RWWVuix6bn_4SmbxLUgcFA"
}

A misspelled column, such as elevationft, is rejected with 403 Forbidden and a message about a function that is not accessible:

Output (HTTP 403 Forbidden):

{
    "code": "Forbidden",
    "title": "Forbidden",
    "message": "The request could not be processed because a function referenced by the SQL statement being evaluated is not accessible or does not exist",
    "type": "tag:oracle.com,2020:error/Forbidden",
    "instance": "tag:oracle.com,2020:ecid/QYew-PgR1xpj2hqvVCBBpg"
}

Things to Know

  • Filters apply only to columns of the enabled object; to filter on a calculated value, add it as a column of a view.
  • Use $instr for "contains" searches, and store or expose values in one case when case-insensitive matching matters.
  • Filters and paging work together: limit and offset apply to the filtered rows.

Related Guides

Conclusion

The q parameter filters AutoREST collections with a JSON query: comparisons, patterns, lists, AND and OR, and sorting, all run as SQL in the database. Encode it in the URL, remember that $like is case-sensitive, and expose a view when clients need different columns to filter on.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted