> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://contentful.com/developers/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://contentful.com/developers/docs/_mcp/server.

# Collection filters

The GraphQL Content API allows users to specify filters on root collection queries.

Collections could be filtered by different fields or combination of fields that contain collection items. There are general and type specific filters:

| Filter            | Postfix             | Field type           |
| ----------------- | ------------------- | -------------------- |
| equal             | *(none)*            | `<any scalar>`       |
| not equal         | `_not`              | `<any scalar>`       |
| exists            | `_exists`           | `<any>`              |
| contains          | `_contains`         | String, RichText     |
| does not contain  | `_not_contains`     | String, RichText     |
| greater than      | `_gt`               | Number, Date         |
| greater or equals | `_gte`              | Number, Date         |
| less than         | `_lt`               | Number, Date         |
| less or equals    | `_lte`              | Number, Date         |
| in given list     | `_in`               | String, Number, Date |
| not in given list | `_not_in`           | String, Number, Date |
| within circle     | `_within_circle`    | Location             |
| within rectangle  | `_within_rectangle` | Location             |
| contains all      | `_contains_all`     | Array                |
| contains some     | `_contains_some`    | Array                |
| contains none     | `_contains_none`    | Array                |

For each content type the schema defines an input type to filter entries of that content type. For example, for the type `FriendlyUser` structured in the following way:

```graphql
type FriendlyUser {
  sys: Sys
  name: String
  age: Integer
}
```

The schema defines the following filter input type:

```graphql
input FriendlyUserFilter {
  sys: SysFilter
  contentfulMetadata: ContentfulMetadataFilter
  name: String
  name_not: String
  name_exists: Boolean
  name_contains: String
  # ... more name filters
  age: Number
  age_gt: Number
  age_lt: Number
  # ... more age filters
  AND: [FriendlyUserFilter]
  OR: [FriendlyUserFilter]
}
```

Filter inputs can be passed to collection queries of their corresponding type to filter out mutations and the result set.

For example, to find all `FriendlyUser`s whose name is "Frank" or "Francine" and who are older than 30 years, write the following query:

```graphql
query {
  friendlyUserCollection(where: {
    AND: [
      {
        OR: [
          { name: "Frank" },
          { name: "Francine" }
        ]
      },
      { age_gt: 30 }
    ],
  }) {
    name
    age
  }
}
```

## Limitations

It is not possible to filter on fields of type `Object` or `RichText`. There's an exemption in the case of the `ContentfulMetadata` type.

`_contains` filter is case insensitive and must be at least 2 characters long to work. The `_contains` filter is analogous to the `[match]` filter in the *REST API* content. Check the [documentation](/references/content-delivery-api/full-text-search-on-a-field) of the `[match]` operator for more information about the details of full-text search in contentful.

For performance reasons it is not recommended to use the `_contains` filter when searching for slugs or text IDs. Please use the equality search instead.

## Filter generation

Filter input types are derived from the content model, just like the output types. For each content type, one filter input type is derived. The user can pass it to the corresponding root collection query.

Each filter input type has the `sys`, `AND`, and `OR` fields as well as additional field type-specific filters for every field.

Name of the filter input type is derived from the output type by appending `Filter` to it.

## Logical connectives

Each filter input type has two special fields `AND` and `OR` used to logically combine filters.

If multiple fields are specified on a filter, they get connected with an implicit `AND`:

```graphql
query {
  friendlyUserCollection(where: {
    OR: [
      { name: "Hans" },
      { name: "Joe" }
    ]
    age_gte: 30,
    age_lte: 40
  }) { name }
}
```

And result in the following equivalent query:

```graphql
query {
  friendlyUserCollection(where: {
    AND: [
      OR: [
        { name: "Hans" },
        { name: "Joe" }
      ],
      { age_gte: 30 },
      { age_lte: 40 }
    ]
  }) { name }
}
```

Both queries return all the friendly users between the age of 30 to 40 and are named either Hans or Joe.

## Filters by field type

For each field in a content type a set of filter fields is added to the content type's filter input type. The type of filters is determined by the [field type](/concepts/data-model#fields).

### `Symbol` and `Text`

GraphQL Content API does not distinguish between `Symbol` and `Text` types and generates the same filters for both.

For example, if the content type `FriendlyUser` has a `Symbol` field `name`, the following types are generated:

```graphql
type FriendlyUser {
  # ... other fields
  name: String
}

input FriendlyUserFilter {
  # ... other field filters

  # Matches if the field is equal to the given value
  name: String
  # Matches if the field is not equal to the given value
  name_not: String
  # Matches if the field exists
  name_exists: Boolean
  # Matches if the field value equal one of the given values
  name_in: [String]
  # Matches if the field value does not equal any of the given values
  name_not_in: [String]
  # Matches if given value is a substring of the field value
  name_contains: String
  # Matches if given value is not a substring of the field value
  name_not_contains: String
}
```

### `Number` and `Integer`

Filter names for `Integer` and `Number` types are the same. They only differ in the input types for values. For `Integer` fields the value type is `Int`, whereas for `Number` fields the type is `Float`.

For example, if the content type `FriendlyUser` has an `Integer` field `age`, the following types are generated:

```graphql
type FriendlyUser {
  # ... other fields
  age: Int
}

input FriendlyUserFilter {
  # ... other field filters

  # Matches if the field is equal to the given value
  age: Int
  # Matches if the field is not equal to the given value
  age_not: Int
  # Matches if the field exists
  age_exists: Boolean
  # Matches if the field value equal one of the given values
  age_in: [Int]
  # Matches if the field value does not equal any of the given values
  age_not_in: [Int]
  # Matches if the field value is strictly smaller than the given value
  age_lt: Int
  # Matches if the field value is smaller than or equal to the given value
  age_lte: Int
  # Matches if the field value is strictly greater than the given value
  age_gt: Int
  # Matches if the field value is greater than or equal to the given value
  age_gte: Int
}
```

### `Boolean`

`Boolean` filter accepts values of type `Boolean` and can only be used on fields with type `Boolean`.

For example, if the content type `FriendlyUser` has a `Boolean` field `employed`, the following types are generated:

```graphql
type FriendlyUser {
  # ... other fields
  employed: Boolean
}

input FriendlyUserFilter {
  # ... other field filters

  # Matches if the field is equal to the given value
  employed: Boolean
  # Matches if the field is not equal to the given value
  employed_not: Boolean
  # Matches if the field exists
  employed_exists: Boolean
}
```

### `Date`

For fields with type `Date` the value types are `DateTime`. The value for filter should be provided as a full DateTime value in ISO-8601 format (e.g. `yyyy-mm-ddThh:mm:ss:sssZ`).

For example, if the content type `FriendlyUser` has a `DateTime` field `birthday`, the following types are generated:

```graphql
type FriendlyUser {
  # ... other fields
  birthday: DateTime
}

input FriendlyUserFilter {
  # ... other field filters

  # Matches if the field is equal to the given value
  birthday: DateTime
  # Matches if the field is not equal to the given value
  birthday_not: DateTime
  # Matches if the field exists
  birthday_exists: Boolean
  # Matches if the field value equal one of the given values
  birthday_in: [DateTime]
  # Matches if the field value does not equal any of the given values
  birthday_not_in: [DateTime]
  # Matches if the field value is strictly smaller than the given value
  birthday_lt: DateTime
  # Matches if the field value is smaller than or equal to the given value
  birthday_lte: DateTime
  # Matches if the field value is strictly greater than the given value
  birthday_gt: DateTime
  # Matches if the field value is greater than or equal to the given value
  birthday_gte: DateTime
}
```

### `Location`

For fields with type `Location` the value types are either `Circle` or `Rectangle`.

The `Circle` scalar type has the following format:

```javascript
{
  lat: 10.11,
  lon: 10.11,
  radius: 10,
}
```

where `lat` and `lon` are coordinates of the center of the circle and `radius` its radius in kilometers.

The `Rectangle` scalar type has the following format:

```javascript
{
  topLeftLat: 40,
  topLeftLon: 13.35,
  bottomRightLat: 41,
  bottomRightLon: 14.36
}
```

where `topLeftLat` with `topLeftLon` are the coordinates of the top left corner of the rectangle, and `bottomRightLat` with `bottomRightLon` are the coordinates of the bottom right corner of the rectangle.

For example, if the content type `FriendlyUser` has a `Location` field `place`, the following types are generated:

```graphql
type FriendlyUser {
  # ... other fields
  place: Location
}

input FriendlyUserFilter {
  # ... other field filters

  # Matches if the position is inside the given circle
  place_within_circle: Circle
  # Matches if the position is inside the given rectangle
  place_within_rectangle: Rectangle
}
```

### `Array`

For Array fields with the value type String. The value for the filter should be an array of string values.

For example, if the content type `FriendlyUser` has an `Array` field `nicknames`, the following types are generated:

```graphql
type FriendlyUser {
  # ... other fields
  nicknames: [String]
}

input FriendlyUserFilter {
  # ... other field filters

  # Matches if the field array contains *all* items provided to the filter
  nicknames_contains_all: [String]
  # Matches if the field array contains at least one item provided to the filter
  nicknames_contains_some: [String]
  # Matches if the field array doesn't contain any item provided to the filter
  nicknames_contains_none: [String]
}
```

### `Link`

For Link fields with a single [`linkContentType`](/references/content-management-api/content-types) validation. Filtering depth is limited to one level of relationships.

The collection filter input type has a property corresponding to the field name. The type of this input filter property has filters for all the linked fields (without nested `Link` fields).

```graphql
type FriendlyUser {
  sys: Sys
  firstbornChild: Child
  # ... other fields
}

type Child {
  name: String
}

input FriendlyUserFilter {
  sys: SysFilter
  contentfulMetadata: ContentfulMetadataFilter
  firstbornChild: FriendlyUserFirstbornChildFilter
  # ... more filters
}

input FriendlyUserFirstbornChildFilter {
  sys: SysFilter
  contentfulMetadata: ContentfulMetadataFilter
  name: String
  name_not: String
  name_exists: Boolean
  name_contains: String
  # ... more name filters
}
```

### `sys` filters

Every filter input type has a `sys` property. The type of the `sys` filter property is the statically defined `SysFilter` type.

```graphql
input FriendlyUserFilter {
  sys: SysFilter
  # ... other fields
}

input SysFilter {
  id: String
  id_not: String
  id_in: [String]
  id_not_in: [String]
  id_contains: String
  id_not_contains: String
}
```

Similar to other field filters the `SysFilter` input type is generated from the `Sys` output type. For each field in the `Sys` type, a set of corresponding filters are added to `SysFilter`.

The following is an example of a query for a list of entries by IDs:

```graphql
query {
  friendlyUserCollection(where: {
    sys: {
      id_in: ["id1", "id2"]
    }
  }) { sys { id } }
}
```

### `contentfulMetadata` filters

Every filter input type has a `contentfulMetadata` property. The type of the `contentfulMetadata` filter property is the statically defined `ContentfulMetadataFilter` type.

```graphql
input EntryCollectionFilter {
  sys: SysFilter
  contentfulMetadata: ContentfulMetadataFilter
}

input ContentfulMetadataFilter {
  tags_exists: Boolean
  tags: ContentfulMetadataTagsFilter
}

input ContentfulMetadataTagsFilter {
  id_contains_some: [String!]
  id_contains_none: [String!]
  id_contains_all: [String!]
}
```

The `ContentfulMetadataFilter` input type is generated from the `tags` field in the `ContentfulMetadata` type and its `id` subfield in the `ContentfulTag` type.

The following is an example of a query for a list of entries across content types by tag presence and tag IDs:

```graphql
query {
  entryCollection(where: {
    contentfulMetadata: {
      tags_exists: true
      tags: {
          id_contains_some: ["tagId1", "tagId2"]
      }
    }
  }) {
    sys {
      id
    }
    contentfulMetadata {
      tags {
        id
      }
    }
  }
}
```

## Nested collection filters

You can filter a multi reference field collection if the field contains a validation rule that makes it accept only specific content types.

If the reference field only accepts a single content type, then you can filter by any field on that content type.

```graphql
query {
  friendlyUserCollection {
    items {
      firstName
      catCollection(where: {name: "foobar"}) {
        items {
          name
        }
      }
    }
  }
}
```

On the other hand, if the reference field accepts multiple content types, then you can filter by any field that is common across all of those content types.

A field is considered common if it has the same `apiName` (field id) and type on all content types. Consider you have the following content types:

* `Cat`
  * field Name: `Cat Name`, field Id: `name`, type: text
  * field Name: `Legs`, field Id: `legs`, type: number
  * field Name: `Lives Left`, field id: `livesLeftOfNine`, type: number
* `Dog`
  * field Name: `Dog Name`, field Id: `name`, type: text
  * field Name: `Legs`, field Id: `legs`, type: boolean
  * field Name: `Likes Walks`, field id: `likesWalks`, type: boolean
* `Person`
  * field Name: `Pets`, field Id: `pets`, type: Reference, validations: Accept only specified entry types: Cat, Dog

On `Person` you will be able to query `petsCollection` by the fields that have the same field id and type on `Cat` and `Dog`. Per our content types definition above: the only common field is `name` (same field id `name` and type `text` on both collections). The field `legs` will not be a common field as its type differs across the content types.

```graphql
query {
  friendlyUserCollection {
    items {
      firstName
      petsCollection(where: {name: "foobar"}) {
        items {
          __typename
          ... on Cat {
            name
            numberOfLivesLeft
          }
          ... on Dog {
            name
            likesGoingForWalks
          }
        }
      }
    }
  }
}
```

The `petsCollection` can be filtered by the fields common to both `Cat` and `Dog` types, such as `name`. It cannot be filtered by fields specific to any one content type, such as `livesLeftOfNine` or `likesGoingForWalks`.

> **Info**
>
> **Note:** When you filter a reference field which accepts more than one content type, the complexity of your query increases by the number of content types the field can accept.