Filters

From SocialStack

Filters are a query-like mechanism for filtering out results from a list endpoint. At their core, they are textual and support a set of arguments.

Filter examples

A textual filter with arguments is like so:

(UserId=? or UserId=?) and CreatedUtc>?

It is not case sensitive. Filters in the permission system do not support these ? arguments (as it wouldn't know where to bind the value from).

Typically you'll see this textual form of filter inside a Where() call in the C# API:

uint userId = 14;

var listOfThingsByThisUser = await Where("UserId=?").Bind(userId).ListAll(context);

.Bind() is used to bind the actual value of an argument. Values are bound in this way such that the filter string is a constant and can benefit from being precompiled. Indeed, the whole filter system is built to be entirely non-allocating, as the Bind calls internally set your provided value onto an compiled object field, with that object originating from a pool for the given cached filter.

JS filter notation

Filters can also be constructed by the frontend, most often by Loop. In this scenario, a convenience filter notation is also available - it'll take the object notation you provide, and then convert it into the textual format with arguments. Here's some examples:

{
    where: {
        userId: 14
    }
}

#Operators can be used by passing an object:

{
    where: {
        userId: {
            greaterThan: 14
        }
    }
}

Or statements are represented with an array:

{
    where: [{
        userId: 14
    },
    {
        userId: 16
    }]
}

And statements are performed by providing multiple field values:

{
    where: {
        userId: 14,
        createdUtc: {
            greaterThan: yesterday /* yesterday is a JS Date */
        }
    }
}

If you need more expressive power, you can also directly specify the query and args:

{
    query: "UserId=?",
    args: [14]
}

Operators

Filters support a variety of operators for comparisons:

  • Greater than
 * Field>?   (query notation)
 * {greaterThan: x}    (JS notation)
  • Less than
 * Field<?   (query notation)
 * {lessThan: x}    (JS notation)
  • Greater than or equal
 * Field>=?   (query notation)
 * {greaterThanOrEqual: x}    (JS notation)
 * {geq: x}    (JS notation)
  • Less than or equal
 * Field<=?   (query notation)
 * {lessThanOrEqual: x}    (JS notation)
 * {leq: x}    (JS notation)
  • Equals
 * Field=?   (query notation)
 * x    (JS notation)
 * {equals: x}    (JS notation)
  • Not
 * Field!=?   (query notation)
 * !( .... )   (query notation)
 * {not: x}    (JS notation)
  • Starts with (textual values only)
 * Field startsWith ?   (query notation)
 * {startsWith: x}    (JS notation)
  • Ends with (textual values only)
 * Field endsWith ?   (query notation)
 * {endsWith: x}    (JS notation)
  • Contains (textual values only)
 * Field contains ?   (query notation)
 * {contains: x}    (JS notation)

Arrays

Todo: Using [?] inside a filter for array-of-things comparisons.

Filter functions

Most often seen in the permission system. These are functions used within a query filter. Filter functions are generic and can also be custom defined by installable modules if you need another. Example code which adds a filter function can be seen on the context extensions page. Variations of UserPermits ("CompanyPermits" etc) are quite common.

  • IsSelf()
  • HasUserPermit()
  • HasRolePermits()
  • IsIncluded()
  • On(...)

Todo: describing the above, particularly On and IsIncluded