Resource Searching

To help find resources quickly, we have a standard approach in searching records. Some older services may provide their own search mechanisms which will be explained in any specific API guides for that service.

Resource searching can be manually done through software like Postman or even the browser, but the SDKs provide several classes which help build up complex search queries.

Each searchable endpoint will have it's own set of filters available to use.


Filters

Filters are used to narrow down datasets. You can add multiple filters to a query across different fields, or even multiple filters on the same field.

In the API guides, any search endpoints will also list which filters are available. Filters are always structured the same way filters.{field}.{comparison}.

As a concrete example, if you wanted to find any user with the email address jane.doe@itccompliance.co.uk, you might use the filter filters.email.equals.

Adding a filter to the query

$query = http_build_query([
  'filters' => [
    'email' => [
      'equals' => 'jane.doe@itccompliance.co.uk',
    ],
  ]
]);

Available Comparisons

Comparisons are used to compare the value we want to use in the filter, against what is stored. For example, using an Equals comparison will do a = database query, whereas using an In comparison would use the IN() query.

The table below details all available comparisons which can be used in queries. Not all endpoints support every comparison. The API guide will explain which comparisons are available for the endpoint.

  • Name
    after
    Required
    Type
    DateTimeInterface
    Description

    Finds records which occurred after a given datetime. Not inclusive.

  • Name
    after_or_on
    Required
    Type
    DateTimeInterface
    Description

    Finds records which occurred after a given datetime. Inclusive.

  • Name
    before
    Required
    Type
    DateTimeInterface
    Description

    Finds records which occurred before a given datetime. Not inclusive.

  • Name
    before_or_on
    Required
    Type
    DateTimeInterface
    Description

    Finds records which occurred before a given datetime. Inclusive.

  • Name
    between
    Required
    Type
    [<integer|DateTimeInterface>, <integer|DateTimeInterface>]
    Description

    Finds records which occur between 2 data points. For example, if searching for ID 3, you can provide [2, 4]. Not Inclusive.

  • Name
    contains
    Required
    Type
    string
    Description

    Finds records which contain a string subset. For example, if you wanted to find all records which had the itccompliance.co.uk domain name, you could use this comparison.

  • Name
    doesnt_contain
    Required
    Type
    string
    Description

    Same as the contains comparison, but the inverse. To find all records which didn't have the domain itccompliance.co.uk, use this filter.

  • Name
    equals
    Required
    Type
    scalar
    Description

    Finds all records which match exactly. This is a loose comparison, stringified numbers are compared equally against integer numbers.

  • Name
    greater_than
    Required
    Type
    integer
    Description

    Similar to the after comparison, but for numbers.

  • Name
    greater_than_or_equal
    Required
    Type
    integer
    Description

    Similar to the after_or_on comparison, but for numbers.

  • Name
    in
    Required
    Type
    array
    Description

    Provides a way to find a group of records. For example, find records with the ID 1 and 2, you'd use this comparison: in:[1,2].

  • Name
    inclusive_between
    Required
    Type
    [<integer|DateTimeInterface>, <integer|DateTimeInterface>]
    Description

    Similar to the between comparison, but inclusive.

  • Name
    less_than
    Required
    Type
    integer
    Description

    Similar to the before comparison, but for numbers.

  • Name
    less_than_or_equal
    Required
    Type
    integer
    Description

    Similar to the before_or_equal comparison, but for numbers.

  • Name
    not_equal
    Required
    Type
    scalar
    Description

    Similar to the equal comparison, but finds records not equal to the value provided.

  • Name
    not_in
    Required
    Type
    array
    Description

    Similar to the in comparison, but excludes matching records.


Complex Filter Example

Filters can be continually added to narrow down the data set returned. The code below shows a complex example. Consider we have a user database, and we want to find all dealer type users, which have the domain name itccompliance.co.uk in the email address, that were created in the year 2022, excluding records with ID 30 and 58, and only records with an ID greater than 20.

Complex Filter Example

use Compliance\Sdk\Search\Search;
use Compliance\Sdk\Search\Filters\GenericFilter;
use Compliance\Sdk\Search\Comparisons\Equals;
use Compliance\Sdk\Search\Comparisons\Contains;
use Compliance\Sdk\Search\Comparisons\Between;
use Compliance\Sdk\Search\Comparisons\NotIn;
use Compliance\Sdk\Search\Comparisons\GreaterThan;

$search = new Search();

$search
  ->add(new GenericFilter('type', new Equals('dealer'));
  ->add(new GenericFilter('email', new Contains('itccompliance.co.uk'))
  ->add(new GenericFilter('created', new Between(
    new DateTime('2022-01-01 00:00:00'),
    new DateTime('2022-12-31 23:59:59')
  ))
  ->add(new GenericFilter('id', new NotIn([30, 58])
  ->add(new GenericFilter('id', new GreaterThan(20));

As you can see, multiple comparisons can be added to the same field to help narrow down records further. All filters are applied using an AND condition.


Ordering results

Result sets can be ordered based on field. By default, the resource type being searched will provide a sensible default search order, which is usually the record ID.

You may add multiple sort orders to the query to sort by primary, secondary etc fields.

Sorting example

use Compliance\Sdk\Search\Search;
use Compliance\Sdk\Search\Orders\Order;

$search = new Search();

$search
  ->order(Order::asc('surname'))
  ->order(Order::desc('forename'));

Orders will be processed in the order they were provided in. In the example above, because we added the surname asc order before the forename desc, results will be ordered by surname ascending first, then forename descending afterwards.

Pagination

The searchable endpoints usually offer several types of pagination, which can be forced through an additional querystring property.

By default, if no result mode is specified, all records will be returned. Obviously this may have a negative effect on some endpoints with large datasets, so please ensure you're paginating where appropriate.

There are 4 different result modes that can be used.

  • Name
    single
    Required
    Type
    deprecated
    Description

    Will return the first record it finds which satisfies the search filters. This result mode is deprecated. You should instead use the Limited result mode with a value of 1.

  • Name
    limited
    Required
    Type
    Description

    Will return a limited number of results without pagination data. For example, if you were only interested in the first 10 results, you can use this.

  • Name
    paginated
    Required
    Type
    Description

    Will return a paginated data set. Depending on the type of pagination used (Paged vs Cursor based), it will return additional context to help you navigate to previous / next pages

  • Name
    all
    Required
    Type
    default
    Description

    Will return all records which satisfy the filters. Use carefully.

Pagination examples

use Compliance\Sdk\Search\Search;
use Compliance\Sdk\Search\ResultModes\Single;

$search = new Search();

$search->mode(new Single());