Skip to content

Filtering, Sorting & Pagination

The find() method accepts a params object with filters, sort, pagination, and fields options. All filter types are generated per-entity, giving you full autocomplete and type safety.

Filters

Comparison Operators

OperatorDescriptionExample
$eqEqual{ title: { $eq: 'Hello' } }
$neNot equal{ status: { $ne: 'draft' } }
$inIn array{ status: { $in: ['published', 'archived'] } }
$ltLess than{ price: { $lt: 100 } }
$lteLess than or equal{ price: { $lte: 100 } }
$gtGreater than{ price: { $gt: 0 } }
$gteGreater than or equal{ price: { $gte: 10 } }
$containsContains substring{ title: { $contains: 'strapi' } }
$startsWithStarts with{ slug: { $startsWith: 'blog-' } }
$endsWithEnds with{ email: { $endsWith: '@company.com' } }
$nullIs null{ deletedAt: { $null: true } }
$notNullIs not null{ publishedAt: { $notNull: true } }

Example:

ts
const result = await strapi.articles.find({
    filters: {
        title: { $contains: 'typescript' },
        views: { $gte: 100 },
        status: { $eq: 'published' },
    },
})

Logical Operators

Combine multiple conditions with $and, $or, and $not:

ts
// $or — match any condition
const result = await strapi.articles.find({
    filters: {
        $or: [
            { title: { $contains: 'strapi' } },
            { title: { $contains: 'nextjs' } },
        ],
    },
})

// $and — match all conditions (implicit when listing multiple fields)
const result = await strapi.articles.find({
    filters: {
        $and: [{ status: { $eq: 'published' } }, { views: { $gt: 50 } }],
    },
})

// $not — negate a condition
const result = await strapi.articles.find({
    filters: {
        $not: {
            status: { $eq: 'draft' },
        },
    },
})

Nested Field Filtering

Filter on fields of related entities:

ts
const result = await strapi.articles.find({
    filters: {
        category: {
            slug: { $eq: 'technology' },
        },
        author: {
            name: { $contains: 'John' },
        },
    },
})

TIP

Nested filters work on relations without needing to populate them. Strapi resolves the join on the server side.

Sorting

Pass an array of sort strings in the format field:direction:

ts
const result = await strapi.articles.find({
    sort: ['createdAt:desc'],
})

// Multiple sort fields
const result = await strapi.articles.find({
    sort: ['featured:desc', 'title:asc'],
})

Valid directions are asc (ascending) and desc (descending). If no direction is specified, asc is used by default.

Pagination

Control the page number and page size:

ts
const result = await strapi.articles.find({
    pagination: {
        page: 1,
        pageSize: 10,
    },
})

// Pagination metadata is in the response
console.log(result.meta.pagination)
// {
//   page: 1,
//   pageSize: 10,
//   pageCount: 5,
//   total: 42,
// }

WARNING

The default page size in Strapi is 25. The maximum page size is 100 unless configured otherwise in your Strapi settings.

Fields Selection

Select only specific fields to reduce response size:

ts
const result = await strapi.articles.find({
    fields: ['title', 'slug', 'createdAt'],
})

// Only the selected fields are returned

Combining Parameters

All parameters can be used together:

ts
const result = await strapi.articles.find({
    filters: {
        status: { $eq: 'published' },
        category: {
            slug: { $in: ['tech', 'science'] },
        },
    },
    sort: ['publishedAt:desc'],
    pagination: {
        page: 1,
        pageSize: 12,
    },
    populate: {
        category: true,
        author: true,
    },
    fields: ['title', 'slug', 'excerpt', 'publishedAt'],
})

Entity-Specific Filter Types

The generated types include filter type definitions for each entity. This means you get autocomplete for field names and type checking for filter values:

ts
// TypeScript will error if you filter on a non-existent field
const result = await strapi.articles.find({
    filters: {
        nonExistentField: { $eq: 'value' }, 
    },
})

// TypeScript will error if the value type doesn't match the field
const result = await strapi.articles.find({
    filters: {
        views: { $eq: 'not a number' }, 
    },
})

INFO

Filter types are generated based on your Strapi schema. When your schema changes and you regenerate types, the filter types update automatically.

Released under the MIT License.