CQL (Common Query Language) is a query language created by the OGC for the Catalogue Web Services specification.
Unlike the XML-based Filter Encoding language, CQL is written using a familiar text-based syntax.
It is thus more readable and better-suited for manual authoring.

However, CQL has some limitations. For example it cannot encode id filters, and it requires an attribute to be on the left side of any comparison operator.
For this reason, GeoServer provides an extended version of CQL called ECQL.
ECQL removes the limitations of CQL, providing a more flexible language with stronger similarities with SQL.

GeoServer supports the use of both CQL and ECQL in WMS and WFS requests, as well as in GeoServer’s SLD dynamic symbolizers.
Whenever the documentation refers to CQL, ECQL syntax can be used as well (and if not, please report that as a bug!).

This tutorial introduces the CQL/ECQL language by example.
For a full reference, refer to the ECQL Reference.

The following examples use the topp:states sample layer shipped with GeoServer.
They demonstrate how CQL filters work by using the WMS CQL_FILTER vendor parameter to alter the data displayed by WMS requests.
The easiest way to follow the tutorial is to open the GeoServer Map Preview for the topp:states layer.
Click on the Options button at the top of the map preview to open the advanced options toolbar.
The example filters can be entered in the Filter: CQL box.

topp:states preview with advanced toolbar open.

The attributes used in the filter examples are those included in the layer.
For example, the following are the attribute names and values for the Colorado feature:

Let’s get started with a simple example. In CQL arithmetic and comparisons
are expressed using plain text. The filter PERSONS>15000000 will select states that
have more than 15 million inhabitants:

PERSONS > 15000000

The full list of comparison operators is: =, <>, >, >=, <, <=.

To select a range of values the BETWEEN operator can be used: PERSONSBETWEEN1000000AND3000000:

PERSONS BETWEEN 1000000 AND 3000000

Comparison operators also support text values. For instance, to select only the state of California, the filter is
STATE_NAME='California'.
More general text comparisons can be made using the LIKE operator. STATE_NAMELIKE'N%' will extract all states starting with an “N”:

STATE_NAME LIKE ‘N%’

It is also possible to compare two attributes with each other. MALE>FEMALE selects the
states in which the male population surpasses the female one (a rare occurrence):

MALE > FEMALE

Arithmetic expressions can be computed using the +,-,*,/ operators.
The filter UNEMPLOY/(EMPLOYED+UNEMPLOY)>0.07 selects all states whose unemployment ratio is above 7% (remember the sample data is very old, so don’t draw any conclusion from the results!)

CQL/ECQL can use any of the filter functions available in GeoServer.
This greatly increases the power of CQL expressions.

For example, suppose we want to find all states whose name contains an “m”, regardless of letter case. We can use the strToLowerCase to turn all the state names to lowercase and then use a like comparison: strToLowerCase(STATE_NAME)like'%m%':

CQL provides a full set of geometric filter capabilities. Say, for example, you want to display only the states that intersect the (-90,40,-60,45) bounding box.
The filter will be BBOX(the_geom,-90,40,-60,45)

BBOX(the_geom, -90, 40, -60, 45)

Conversely, you can select the states that do not intersect the bounding box with the filter: DISJOINT(the_geom,POLYGON((-9040,-9045,-6045,-6040,-9040))):