Advanced Querying and Filtering in the UI

The advanced querying mechanism allows you to perform filtering, sorting, and querying directly from the UI. Queries are sent to the API and executed by the advanced query engine.

This enables developers to build flexible and powerful data retrieval scenarios without writing custom query logic for every use case.

Example: Querying Activities

The following example shows how to use a MultiQuery with filters and sorting to retrieve activities.

private async Task<List<Activity>> GetActivitiesAsync()
{
    var tenantName = runContext.GetActiveTenantName();

    // Specify advanced query filter and sorting
    var multiQuery = new MultiQuery()
    {
        ContextEntities = [],
        Filter = FilterBuilder.And(
            FilterBuilder.Field("Closed").Eq(false),
            FilterBuilder.Field("Prio").Gt(0)
        ),
        Sort = SortBuilder.By(SortBuilder.Asc("Name")),
    };

    var queryResult = await queryDispatcher.QueryAsync<EntityQuery, MultiQueryResult>(
        new EntityQuery()
        {
            AppName = AppConstants.App.Name,
            TenantName = tenantName,
            EntityClassName = nameof(Activity),
            MultiQuery = multiQuery,
        }
    );

    return [.. queryResult.Entities.OfType<Activity>()];
}

MultiQuery Structure

A MultiQuery can include:

  • ContextEntities – optional context entities to scope the query.

  • Filter – one or more filters built with FilterBuilder.

  • Sort – sorting criteria built with SortBuilder.


Filtering

Filters are constructed using the FilterBuilder API. Each filter targets a specific field and applies an operator. Filters can be combined with And and Or.

Filter Operators

Method
Operator
Example Code

Eq(value)

Equals

FilterBuilder.Field("Status").Eq("Active")

Ne(value)

Not equals

FilterBuilder.Field("Status").Ne("Closed")

Gt(value)

Greater than

FilterBuilder.Field("Prio").Gt(0)

Gte(value)

Greater than or equal

FilterBuilder.Field("Prio").Gte(5)

Lt(value)

Less than

FilterBuilder.Field("Prio").Lt(10)

Lte(value)

Less than or equal

FilterBuilder.Field("Prio").Lte(20)

In(values)

In list

FilterBuilder.Field("Category").In(new[] { "A", "B", "C" })

Nin(values)

Not in list

FilterBuilder.Field("Category").Nin(new[] { "Archived", "Deleted" })

Contains(value)

Contains substring (for text)

FilterBuilder.Field("Name").Contains("Test")

Combining Filters

  • AND:

    FilterBuilder.And(
        FilterBuilder.Field("Closed").Eq(false),
        FilterBuilder.Field("Prio").Gt(0)
    )
  • OR:

    FilterBuilder.Or(
        FilterBuilder.Field("Category").Eq("A"),
        FilterBuilder.Field("Category").Eq("B")
    )

Sorting

Sorting is applied using SortBuilder.

Sort = SortBuilder.By(
    SortBuilder.Desc("Prio"),
    SortBuilder.Asc("Name")
)

Executing the Query

Queries are dispatched using QueryDispatcher:

var queryResult = await queryDispatcher.QueryAsync<EntityQuery, MultiQueryResult>(
    new EntityQuery()
    {
        AppName = AppConstants.App.Name,
        TenantName = tenantName,
        EntityClassName = nameof(Activity),
        MultiQuery = multiQuery,
    }
);

The result contains the matching entities:

return [.. queryResult.Entities.OfType<Activity>()];

Summary

  • MultiQuery defines filters, sorting, and context entities.

  • FilterBuilder supports equality, comparison, set membership, and text operators.

  • SortBuilder supports multi-field sorting in ascending or descending order.

  • Queries execute via QueryDispatcher and return a MultiQueryResult.

This mechanism provides a flexible, UI-driven querying model that integrates seamlessly with the Bloqs API.

Last updated