Column filters

A column-based filter allows you to filter CARTO + deck.gl sources and layers dynamically, without modifying your original SQL query or resource, while fully leveraging your cloud data warehouse computing power.

Typically, column-based filters originate from user inputs in the UI of your application, most commonly from CARTO Widgets (eg: clicking in a category of a category widget filters the map for that category)

Using filters

Filters are an object-type property that is accepted by:

import {vectorTableSource} from 'carto-api-client';

// init your data source with filters

const myFilters = {};

const data = await vectorTableSource({
    ...cartoCredentials,
    tableName: 'carto-demo-data.demo_tables.osm_pois_usa',
    filters: myFilters
});

Managing different sets of filters

Filter functions

To manage your filters, use any of the following functions

addFilter

Adds a filter to a filter object.

Usage

import {vectorTableSource, addfilter, FilterType} from 'carto-api-client';

addFilter(myFilters, {
  column: 'column_name',
  type: FilterType.BETWEEN,
  values: [[0, 100]],
  owner: 'my-widget' // OPTIONAL: this filter won't affect models with 'my-widget' as filterOwner
})

Properties

  • column: STRING the name of the column that this filter will be applied too

  • type: FilterType the filter operation. Check FilterType for a list of accepted values.

  • values: a set of values to filter. The expected format is dependant on the selected type.

  • owner (Optional): STRING this filter won't affect widget models that have a matching filterOwner property. Check Preventing specific widgets from being filtered.

removeFilter

Removes all filters from a filter object that match that column (or column + owner).

Usage

import {vectorTableSource, removeFilter} from 'carto-api-client';

removeFilter(myFilters, {
  column: 'column_name',
  owner: 'my-widget' // OPTIONAL: remove only filters that originally included this owner
})

Properties

  • column: STRING all filters affecting this column will be removed (unless owner is specified)

  • owner: STRING if specified, the removed filters will be only the ones matching exactly the column + owner combination.

clearFilter

Removes all filters from a filter object.

Usage

import {vectorTableSource, clearFilter} from 'carto-api-client';

clearFilter(myFilters)

getFilter

Returns all the current filters and its values for a given filter inside a filter object.

Usage

import {vectorTableSource, getFilter} from 'carto-api-client';

getFilter(myFilters, {
  column: 'column_name',
  owner: 'my-widget' // OPTIONAL: remove only filters that originally included this owner
})

Properties

  • column: STRING the name of the column we're checking for filters

  • owner: STRING if specified, this function will only check filters matching exactly the column + owner combination.

hasFilter

Returns a boolean: true if there are already filters that match the specified properties, false if there are no filters matching them.

Usage

import {vectorTableSource, hasFilter} from 'carto-api-client';

hasFilter(myFilters, {
  column: 'column_name',
  owner: 'my-widget' // OPTIONAL: remove only filters that originally included this owner
})

Properties

  • column: STRING the name of the column we're checking for filters

  • owner: STRING if specified, this function will only check filters matching exactly the column + owner combination.

FilterType

This type contains the different filter types allowed in addFilter

Usage

import {FilterType} from 'carto-api-client';

Values

FilterType
Expected value
Description

FilterType.IN

number[] | string[]

Filter rows matching exactly these values. Example: ['Madrid', 'New York']

FilterType.BETWEEN

number[][]

Filter rows between those values. [a, b] both are included. Example: [[0, 300]]

FilterType.CLOSED_OPEN

number[][]

Filter rows between those values. [a, b) a is included, b is not. Example: [[0, 300]]

FilterType.TIME

number[][]

Similar to BETWEEN, but more suitable for date or timestamp columns. [a, b] both are included: ['964656085544', '1021247914455']

FilterType.STRING_SEARCH

string[]

Filter rows soft-matching these values. The results will be ordered with the exact matches first. Example: ['Madrid'] will also return rows with madrid or Madrid Centro

getDataFilterExtensionProps

Use this function to convert a valid set of filters into the properties expected by deck.gl DataFilterExtension to achieve GPU-based filtering (client-side filtering) of your CARTO + deck.gl layers. Useful when combined with client-side widgets.

Usage

import {vectorTableSource, getDataFilterExtensionProps} from 'carto-api-client';
import {Deck} from '@deck.gl/core';
import {VectorTileLayer} from '@deck.gl/carto';
import {DataFilterExtension} from '@deck.gl/extensions';


const layers = [
  new VectorTileLayer({
    data: dataSource,
    extensions: [new DataFilterExtension({filterSize: 4})],
    ...getDataFilterExtensionProps(myFilters) 
    // ...getDataFilterExtensionProps(filters, filtersLogicalOperator, filterSize)
  })
];

Properties

  • filters: A valid Filters object.

  • filtersLogicalOperator: Indicates whether filters are applied following an AND logic or an OR logic. Must be a string 'and' | 'or' .

  • fIlterSize: An integer 2, 3, or 4. Must match the filterSize used to create the DataFilterExtension.

Preventing specific widgets from being filtered

Sometimes widgets are used to filter the data, for example, when clicking in a category or a pie sector. If the filter was also applied to the widget, the result could be undesired, as the widget itself would lose all the other values.

To prevent this, simply make sure to assign your widget an arbitrary string identifier via filterOwner and then use that same identifier in your addFilter calls.

Example of a filter not applying to a widget

import {vectorTableSource, addfilter, FilterType} from 'carto-api-client';

const myFilters = {};

const data = await vectorTableSource({
   ...credentials,
   tableName: 'my-data.data.table',
   filters: myFilters
});

addFilter(myFilters, {
  column: 'column_name',
  type: FilterType.BETWEEN,
  values: [[0, 100]],
  owner: 'cat-widget' // this filter doesn't apply
})

const excludedWidget = data.widgetSource.getCategories({
  column: 'group_name',
  operation: 'count',
  filterOwner: 'cat-widget' // to widgets with filterOwner === 'cat-widget'
})

In this example, all layers depending on data would be filtered (therefore the map would be filtered) but the widget would still show all the categories, allowing for subsequent interactions.

Last updated

Was this helpful?