Skip to main content

Query Helpers

The @nestjs-query/core package provides a number of helper functions to transform or apply queries to a list of items.

An example use case for these helpers would be to write a QueryService that wraps a store that does not support the query options natively (e.g. An in memory collection of objects such as a static array of objects).

All examples will be based on the following DTO definition.

interface TestDTO {  first?: string | null;
  last?: string | null;
  age?: number | null;
  isVerified?: boolean | null;
  created?: Date | null;}

applyFilter#

The applyFilter helper applies a Filter to a single object or an array of objects.

Arguments#

  • dto: DTO|DTO[]
    • If a single object a function that will test the dto against the filter, returning true when if it matches the filter.
    • If an array of objects is provided the array will be filtered returning a new array with all elements that match the filter.
  • filter: Filter<DTO> - The filter to check the object[s] against. See Filtering

Example#

import { applyFilter } from `@nestjs-query/core`;
const dtos: TestDTO[] = [  {first: 'Bob', last: 'Yukon'}  {first: 'Alice', last: 'Yukon'}  {first: 'Sally', last: 'Yukon'}  {first: 'Zane', last: 'Yukon'}]const filtered = applyFilter(dtos, {first: {in: ['Bob', 'Sally']})
const dto: TestDTO = {first: 'Bob', last: 'Yukon'};applyFilter<TestDTO>(dto, {first: {in: ['Bob', 'Sally']}) // trueapplyFilter<TestDTO>(dto, {first: {eq: ['Alice', 'Zane']}) // false

applySort#

The applySort will sort an array of dtos.

info

Because applySort uses the native Array#sort method it may not exactly match the ordering you would expect from a database.

warning

It is expected that your data types all match. For example if you have a number field that also has some numbers represented as strings the applySort method may not work as expected.

Arguments#

  • dto: DTO[] - The array of DTOs to sort.
  • sortFields: SortField<DTO>[] - The sorting criteria. See Sorting

Example#

import { applySort, SortDirection, SortNulls } from `@nestjs-query/core`;
const dtos: TestDTO[] = [  {first: 'Bob', last: 'Yukon'}  {first: 'Alice', last: 'Yukon'}  {first: null, last: 'Yukon'}  {first: 'Sally', last: 'Yukon'}  {last: 'Yukon'}  {first: 'Zane', last: 'Yukon'}]const sorted = applySort(dtos, [   { field: 'first', direction: SortDirection.DESC, nulls: SortNulls.NULLS_LAST },])

The resulting sorted array would be.

[  {first: 'Zane', last: 'Yukon'}  {first: 'Sally', last: 'Yukon'}  {first: 'Bob', last: 'Yukon'}  {first: 'Alice', last: 'Yukon'}  {first: null, last: 'Yukon'}  {last: 'Yukon'}]

applyPaging#

The applyPaging method will apply a limit and/or offset to an array of dtos.

Arguments#

  • dto: DTO[] - The array of DTOs to page.
  • paging: Paging - The paging arguments to apply. See Paging

Example#

import { applyPaging } from `@nestjs-query/core`;const dtos: TestDTO[] = [  {first: 'Bob', last: 'Yukon'}  {first: 'Alice', last: 'Yukon'}  {first: 'Sally', last: 'Yukon'}  {first: 'Zane', last: 'Yukon'}]const paged = applyPaging(dtos, {offset: 1, limit: 2})

The resulting paged dtos would be.

[  {first: 'Alice', last: 'Yukon'}  {first: 'Sally', last: 'Yukon'}]

applyQuery#

The applyQuery uses the applyFilter, applySorting, and applyPaging methods to apply a Query to an array of DTOs.

Arguments#

  • dto: DTO[] - The array of DTOs to page.
  • query: Query<DTO> - The query to apply to the array of dtos. See Queries

Example#

import { applyQuery, SortDirection } from `@nestjs-query/core`;
const dtos: TestDTO[] = [  {first: 'Bob', last: 'Yukon', isVerified: true}  {first: 'Alice', last: 'Yukon', isVerified: false}  {first: 'Sally', last: 'Yukon', isVerified: true}  {first: 'Zane', last: 'Yukon', isVerified: true}]const queryResult = applyQuery(dtos, {  filter: { isVerified: { is: true } },  sorting: [{ field: 'first', direction: SortDirection.DESC }],  paging: { offset: 1, limit: 2 }})

The resulting array of dtos would be.

[  {first: 'Sally', last: 'Yukon', isVerified: true}  {first: 'Bob', last: 'Yukon', isVerified: true}]

transformFilter#

The transformFilter is used to remap fields in a Filter. This method is commonly used when defining a custom Assembler.

Arguments#

  • filter: Filter<From> - The filter you want to transform.
  • fieldMap: QueryFieldMap<From, To> - A map of fields where the key is a key in the From type, and the value is a key in the to type.

Example#

import { transformFilter, QueryFieldMap, Filter } from `@nestjs-query/core`;
class TestEntity {  firstName!: string;
  lastName!: string;}
const fieldMap: QueryFieldMap<TestDTO, TestEntity> = {  first: 'firstName',  last: 'lastName',};
const dtoFilter: Filter<TestDTO> = {  first: { eq: 'foo' },  last: { neq: 'bar' },};
const transformed = transformFilter(dtoFilter, fieldMap);

The new filter would be

{  firstName: { eq: 'foo' },  lastName: { neq: 'bar' },}

transformSort#

The transformSort is used to remap fields in an array of SortField<DTO>[]. This method is commonly used when defining a custom Assembler.

Arguments#

  • sortFields: SortField<From>[] - The array of sorting criteria to transform.
  • fieldMap: QueryFieldMap<From, To> - A map of fields where the key is a key in the From type, and the value is a key in the to type.

Example#

import { transformSort, QueryFieldMap, SortField, SortDirection } from `@nestjs-query/core`;
class TestEntity {  firstName!: string;
  lastName!: string;}
const fieldMap: QueryFieldMap<TestDTO, TestEntity> = {  first: 'firstName',  last: 'lastName',};const dtoSort: SortField<TestDTO>[] = [  { field: 'first', direction: SortDirection.DESC },  { field: 'last', direction: SortDirection.ASC },];
const transformed = transformSort(dtoSort, fieldMap);
[  { field: 'firstName', direction: SortDirection.DESC },  { field: 'lastName', direction: SortDirection.ASC },];

transformQuery#

The transformQuery method uses the transformFilter and transformSort methods to remap a Query. This method is commonly used when defining a custom Assembler.

Arguments#

  • sortFields: Query<From> - The query to transform.
  • fieldMap: QueryFieldMap<From, To> - A map of fields where the key is a key in the From type, and the value is a key in the to type.

Example#

import { transformQuery, QueryFieldMap, Query, SortDirection } from `@nestjs-query/core`;
class TestEntity {  firstName!: string;
  lastName!: string;}
const fieldMap: QueryFieldMap<TestDTO, TestEntity> = {  first: 'firstName',  last: 'lastName',};const dtoQuery: Query<TestDTO> = {  filter: { first: { eq: 'foo' }, last: { neq: 'bar' } }  sorting: [    { field: 'first', direction: SortDirection.DESC },    { field: 'last', direction: SortDirection.ASC },  ]};
const transformed =  transformQuery(dtoQuery, fieldMap);

The resulting query would be.

{  filter: { firstName: { eq: 'foo' }, lastName: { neq: 'bar' } }  sorting: [    { field: 'firstName', direction: SortDirection.DESC },    { field: 'lastName', direction: SortDirection.ASC },  ]}

getFilterComparisons#

Used to search a filter get a list of comparison objects for a given key.

Arguments#

  • filter: Filter<DTO> - The filter to search.
  • key: keyof DTO - The key in the DTO object to search for in the filter object.

Example#

import { Filter, getFilterComparisons } from `@nestjs-query/core`;
class TestDTO {  age!: number;
  title!: string;}
const filter: Filter<TestDTO> = {  age: { gte: 10 },  or: [{ title: { like: '%bar' } }, { title: { eq: 'foobar' } }],};
const comparisons = getFilterComparisons(filter, 'title');

The resulting array would be

[{ like: '%bar' }, { eq: 'foobar' }];

getFilterOmitting#

Used to get a filter with a given key removed.

Arguments#

  • filter: Filter<DTO> - The filter containing the unwanted key.
  • key: keyof DTO - The key in the DTO object to remove in the filter object.

Example#

import { Filter, getFilterOmitting } from `@nestjs-query/core`;
class TestDTO {  age!: number;
  title!: string;}
const filter: Filter<TestDTO> = {  age: { gte: 10 },  or: [{ title: { like: '%bar' } }, { title: { eq: 'foobar' } }],};
const filterWithoutTitle = getFilterOmitting(filter, 'title');

The resulting filter would be

{  age: { gte: 10 },}