Functions API Reference
Complete reference for the dcupl SDK analytical functions (dcupl.fn).
Overview
The Functions API provides data analysis capabilities including aggregations, facets, suggestions, grouping, and pivot tables.
// Access via dcupl instance
dcupl.fn.facets({ ... });
dcupl.fn.aggregate({ ... });
dcupl.fn.suggest({ ... });
dcupl.fn.groupBy({ ... });
dcupl.fn.pivot({ ... });
dcupl.fn.metadata({ ... });
// Or via list catalog
list.catalog.fn.facets({ ... });facets()
Generates faceted filter options with counts for building filter UIs.
Signature:
facets(options: FacetOptions): FacetResult[]Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.attribute |
string |
Yes | Property to generate facets for |
options.count |
number |
No | Maximum number of facets |
options.excludeZeros |
boolean |
No | Exclude facets with zero count |
options.excludeUndefineds |
boolean |
No | Exclude facets with undefined values |
options.calculateResults |
boolean |
No | Calculate result keys for each facet |
Returns: DcuplFacet[]
type DcuplFacet = {
key: string; // Unique facet key
enabled: boolean; // Whether facet is enabled
selected: boolean; // Whether facet is currently selected
size: number; // Number of items with this value
value: any; // The facet value
entry?: any; // Referenced entry if applicable
resultKeys?: string[]; // Keys of matching items (if calculateResults is true)
children?: DcuplFacet[]; // Nested facets for hierarchical data
};Examples:
const categories = dcupl.fn.facets({
modelKey: 'Product',
options: { attribute: 'category' },
});
// Returns:
// [
// { key: 'electronics', value: 'electronics', size: 45, enabled: true, selected: false },
// { key: 'clothing', value: 'clothing', size: 32, enabled: true, selected: false },
// { key: 'books', value: 'books', size: 28, enabled: true, selected: false }
// ]const topBrands = dcupl.fn.facets({
modelKey: 'Product',
options: {
attribute: 'brand',
count: 10,
excludeZeros: true,
excludeUndefineds: true,
},
});const list = dcupl.lists.create({ modelKey: 'Product' });
list.catalog.query.addCondition({
operator: 'eq',
attribute: 'status',
value: 'active',
});
// Facets reflect filtered data
const facets = list.catalog.fn.facets({
attribute: 'category',
});const suppliers = dcupl.fn.facets({
modelKey: 'Product',
options: { attribute: 'supplier' },
});
// Returns reference objects with entry:
// [{ key: 's1', value: 's1', size: 20, enabled: true, selected: false, entry: { key: 's1', name: 'Supplier A' } }]aggregate()
Performs aggregation calculations on numeric properties.
Signature:
aggregate(options: AggregateOptions): AggregateResultParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.attribute |
string |
Yes | Numeric property to aggregate |
options.types |
AggregationType[] |
Yes | Aggregation types to calculate |
Aggregation Types: 'sum', 'avg', 'min', 'max', 'count'
Returns: AggregateResult
type AggregateResult = {
sum?: number;
avg?: number;
min?: number;
max?: number;
count?: number;
};Examples:
const priceStats = dcupl.fn.aggregate({
modelKey: 'Product',
options: {
attribute: 'price',
types: ['sum', 'avg', 'min', 'max', 'count'],
},
});
// Returns:
// {
// sum: 25000,
// avg: 250,
// min: 9.99,
// max: 999.99,
// count: 100
// }const expensiveStats = dcupl.fn.aggregate({
modelKey: 'Product',
query: {
modelKey: 'Product',
queries: [{ operator: 'gte', attribute: 'price', value: 100 }],
},
options: {
attribute: 'price',
types: ['avg', 'count'],
},
});const list = dcupl.lists.create({ modelKey: 'Order' });
const orderStats = list.catalog.fn.aggregate({
attribute: 'total',
types: ['sum', 'avg'],
});suggest()
Provides autocomplete suggestions based on partial text input.
Signature:
suggest(options: SuggestOptions): string[]Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.attribute |
string |
Yes | Property to search |
options.value |
any |
Yes | Search term to match against |
options.max |
number |
No | Maximum suggestions (default: 10) |
Returns: string[] - Array of matching values
Examples:
const suggestions = dcupl.fn.suggest({
modelKey: 'Product',
options: {
attribute: 'name',
value: 'lap',
max: 5,
},
});
// Returns: ['Laptop', 'Laptop Pro', 'Laptop Stand', 'Lapel Pin']const suggestions = dcupl.fn.suggest({
modelKey: 'Product',
query: {
modelKey: 'Product',
queries: [{ operator: 'eq', attribute: 'category', value: 'electronics' }],
},
options: {
attribute: 'name',
value: 'phone',
},
});
// Only suggests from electronics categoryconst list = dcupl.lists.create({ modelKey: 'Product' });
list.catalog.query.addCondition({
operator: 'eq',
attribute: 'status',
value: 'active',
});
const suggestions = list.catalog.fn.suggest({
attribute: 'name',
value: 'wire',
});
// Suggestions from active products onlygroupBy()
Groups items by a property value.
Signature:
groupBy(options: GroupByOptions): Record<string, T[]>Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.attribute |
string |
Yes | Property to group by |
Returns: Record - Object with group keys and item arrays
Examples:
const grouped = dcupl.fn.groupBy({
modelKey: 'Product',
options: { attribute: 'category' },
});
// Returns:
// {
// 'electronics': [{ key: 'p1', ... }, { key: 'p2', ... }],
// 'clothing': [{ key: 'p3', ... }],
// 'books': [{ key: 'p4', ... }, { key: 'p5', ... }]
// }const grouped = dcupl.fn.groupBy({
modelKey: 'Order',
query: {
modelKey: 'Order',
queries: [{ operator: 'eq', attribute: 'status', value: 'completed' }],
},
options: { attribute: 'customer.key' },
});
// Groups completed orders by customerconst list = dcupl.lists.create({ modelKey: 'Product' });
const byBrand = list.catalog.fn.groupBy({
attribute: 'brand',
});pivot()
Creates pivot table aggregations with row and column dimensions.
Signature:
pivot(options: PivotOptions): PivotResultParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.rows |
PivotRowOption[] |
Yes | Row dimension configurations |
options.columns |
PivotColumnOption[] |
Yes | Column dimension configurations |
options.values |
AggregationOptions[] |
Yes | Value aggregation configurations |
Type definitions:
type PivotRowOption = {
attribute: string; // Property to use as row dimension
};
type PivotColumnOption = {
attribute: string; // Property to use as column dimension
};
type AggregationOptions = {
attribute: string; // Property to aggregate
type: AggregationType; // 'sum' | 'avg' | 'min' | 'max' | 'count'
};Returns: PivotResult - Pivot table data structure
Examples:
const salesPivot = dcupl.fn.pivot({
modelKey: 'Order',
options: {
rows: [{ attribute: 'customer.region' }],
columns: [{ attribute: 'orderDate' }],
values: [{ attribute: 'total', type: 'sum' }],
},
});
// Returns pivot with regions as rows, dates as columns, summed totalsconst productPivot = dcupl.fn.pivot({
modelKey: 'OrderItem',
options: {
rows: [{ attribute: 'product.category' }, { attribute: 'product.brand' }],
columns: [{ attribute: 'order.year' }],
values: [
{ attribute: 'quantity', type: 'sum' },
{ attribute: 'revenue', type: 'sum' },
],
},
});const filteredPivot = dcupl.fn.pivot({
modelKey: 'Order',
query: {
modelKey: 'Order',
queries: [{ operator: 'gte', attribute: 'orderDate', value: new Date('2024-01-01') }],
},
options: {
rows: [{ attribute: 'customer.tier' }],
columns: [{ attribute: 'status' }],
values: [{ attribute: 'total', type: 'avg' }],
},
});metadata()
Returns metadata about a query result set.
Signature:
metadata(options?: MetadataOptions): MetadataResultParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options |
MetadataOptions |
No | Optional query context |
Returns: MetadataResult
type MetadataResult = {
count: number; // Items matching current query
totalCount: number; // Total items in model
};Examples:
const meta = dcupl.fn.metadata({
modelKey: 'Product',
});
// Returns: { count: 100, totalCount: 100 }const meta = dcupl.fn.metadata({
modelKey: 'Product',
query: {
modelKey: 'Product',
queries: [{ operator: 'eq', attribute: 'status', value: 'active' }],
},
});
// Returns: { count: 85, totalCount: 100 }const list = dcupl.lists.create({ modelKey: 'Product' });
list.catalog.query.addCondition({
operator: 'gte',
attribute: 'price',
value: 50,
});
const meta = list.catalog.fn.metadata();
// Returns count of products >= $50 vs totalCustom Operators
Register custom query operators for specialized filtering logic.
Signature:
dcupl.query.registerCustomOperator(
operator: string,
fn: (query: DcuplQuery, listItem: ListItem) => boolean
): voidParameters passed to custom operator function:
| Parameter | Type | Description |
|---|---|---|
query |
DcuplQuery |
The query object containing attribute, operator, and value |
listItem |
ListItem |
The list item being evaluated, with data property containing item values |
Examples:
dcupl.query.registerCustomOperator('$between', (query, listItem) => {
const value = listItem.data[query.attribute];
const [min, max] = query.value as [number, number];
return value >= min && value <= max;
});
// Usage
dcupl.query.execute({
modelKey: 'Product',
queries: [{ attribute: 'price', operator: '$between', value: [100, 500] }],
});dcupl.query.registerCustomOperator('$fuzzy', (query, listItem) => {
const value = listItem.data[query.attribute];
const pattern = query.value as string;
// Simple fuzzy matching
const regex = new RegExp(pattern.split('').join('.*'), 'i');
return regex.test(value);
});
// Usage
dcupl.query.execute({
modelKey: 'Product',
queries: [
{ attribute: 'name', operator: '$fuzzy', value: 'lptp' }, // matches "laptop"
],
});dcupl.query.registerCustomOperator('$nearBy', (query, listItem) => {
const location = listItem.data[query.attribute];
const { lat, lng, radius } = query.value as { lat: number; lng: number; radius: number };
const distance = calculateDistance(location.lat, location.lng, lat, lng);
return distance <= radius;
});
// Usage
dcupl.query.execute({
modelKey: 'Store',
queries: [
{
attribute: 'location',
operator: '$nearBy',
value: { lat: 40.7128, lng: -74.006, radius: 10 },
},
],
});Complete Examples
Faceted Search Implementation
const list = dcupl.lists.create({
modelKey: 'Product',
listKey: 'search',
});
// Get available facets
function getFacets() {
return {
categories: list.catalog.fn.facets({ attribute: 'category' }),
brands: list.catalog.fn.facets({ attribute: 'brand' }),
priceRanges: list.catalog.fn.facets({ attribute: 'priceRange' }),
};
}
// Apply facet filter
function applyFacet(attribute: string, value: any) {
list.catalog.query.addCondition({
operator: 'eq',
attribute,
value,
queryKey: `facet-${attribute}`,
});
}
// Remove facet filter
function removeFacet(attribute: string) {
list.catalog.query.removeCondition({
queryKey: `facet-${attribute}`,
});
}
// Get results with metadata
function getResults() {
return {
items: list.catalog.query.items(),
meta: list.catalog.fn.metadata(),
facets: getFacets(),
};
}Dashboard Analytics
function getDashboardData() {
// Product statistics
const productStats = dcupl.fn.aggregate({
modelKey: 'Product',
options: {
attribute: 'price',
types: ['avg', 'min', 'max', 'count'],
},
});
// Sales by category
const salesByCategory = dcupl.fn.pivot({
modelKey: 'OrderItem',
options: {
rows: [{ attribute: 'product.category' }],
columns: [],
values: [{ attribute: 'revenue', type: 'sum' }],
},
});
// Top customers
const topCustomers = dcupl.fn.groupBy({
modelKey: 'Order',
options: { attribute: 'customer.key' },
});
// Inventory alerts
const lowStock = dcupl.fn.metadata({
modelKey: 'Product',
query: {
modelKey: 'Product',
queries: [{ operator: 'lt', attribute: 'stock', value: 10 }],
},
});
return {
productStats,
salesByCategory,
topCustomers: Object.entries(topCustomers)
.map(([key, orders]) => ({
customer: key,
orderCount: orders.length,
totalSpent: orders.reduce((sum, o) => sum + o.total, 0),
}))
.sort((a, b) => b.totalSpent - a.totalSpent)
.slice(0, 10),
lowStockCount: lowStock.count,
};
}Search Autocomplete
const list = dcupl.lists.create({ modelKey: 'Product' });
async function getAutocomplete(term: string) {
if (term.length < 2) return [];
const suggestions = list.catalog.fn.suggest({
attribute: 'name',
value: term,
max: 8,
});
// Also get category suggestions
const categoryMatches = list.catalog.fn.suggest({
attribute: 'category',
value: term,
max: 3,
});
return {
products: suggestions,
categories: categoryMatches,
};
}See Also
- Facets Analysis - Detailed facet guide
- Aggregations - Aggregation patterns
- Suggestions - Autocomplete implementation
- Pivot Tables - Pivot table guide
- Faceted Search Pattern - Complete example