Database Utility Functions
Comprehensive guide to the automatically generated database utility functions for each data object in your Mindbricks service. These functions provide a safe, consistent way to interact with your data while ensuring Elasticsearch synchronization and Kafka event publishing.
Mindbricks automatically generates a comprehensive set of database utility functions for each data object in your service. These functions are available through the dbLayer module and provide a safe, consistent interface for data operations that automatically handles:
- Database operations (create, read, update, delete)
- Elasticsearch indexing and synchronization
- Kafka event publishing on data changes
- Soft delete handling
- Data normalization via
getData()
Always use these utility functions instead of directly accessing models to ensure data consistency across your system.
Important: All create, update, and delete functions accept an optional context parameter as the last argument. When calling these functions from Business API actions, pass this as the context to automatically include session and requestId information in events. See the Context Parameter section for details.
Importing dbLayer
// Using destructuring (recommended)
const { getUserById, createUser, updateUserById } = require("dbLayer");
// Or using the full module
const DB = require("dbLayer");
All functions follow the naming pattern: <operation>${ModelName}, where ModelName is the PascalCase name of your data object. For example, if your data object is named order, the functions will be prefixed with Order (e.g., createOrder, getOrderById).
Create Functions
create${ModelName}(data, context)
Creates a single record. If an id is provided and the record already exists, it will update the existing record instead.
Signature:
create${ModelName}(data: Object, context?: Object): Promise<Object>
Parameters:
data(Object) — The data object to create. Must contain all required fields as defined in your data object schema.context(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthisto provide session and request context.
Returns:
- Object — The created/updated record data (normalized via
getData())
Behavior:
- Automatically generates a UUID for
idif not provided - Generates
codenameautomatically if the data object has codename support and a base name field is provided - If
idexists in database, updates the existing record (useful for upsert scenarios) - Automatically indexes the record in Elasticsearch
- Publishes Kafka events for the creation/update (includes session and requestId from context if provided)
Example:
const { createOrder } = require("dbLayer");
// Create a new order (without context)
const order = await createOrder({
userId: "user-123",
totalAmount: 5000,
currency: "USD",
status: "pending"
});
// Create with context (from Business API action)
const order = await createOrder({
userId: "user-123",
totalAmount: 5000,
currency: "USD",
status: "pending"
}, this); // Pass 'this' to include session and requestId
// If order with this ID exists, it will update instead
const updated = await createOrder({
id: order.id,
status: "paid"
}, this);
createBulk${ModelName}(dataList, context)
Creates multiple records in bulk. Uses optimized bulk operations for better performance.
Signature:
createBulk${ModelName}(dataList: Array<Object>, context?: Object): Promise<Array<Object>>
Parameters:
dataList(Array) — Array of data objects to create. Must be a non-empty array.context(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Array — Array of created/updated record data objects
Behavior:
- Validates that
dataListis a non-empty array - Uses bulk database operations for optimal performance
- Handles existing records (updates) and new records (creates) separately
- Each item follows the same rules as
create${ModelName} - Automatically indexes all records in Elasticsearch (in parallel)
- Publishes Kafka events for each creation/update (includes session and requestId from context if provided)
Example:
const { createBulkOrder } = require("dbLayer");
// Without context
const orders = await createBulkOrder([
{ userId: "user-1", totalAmount: 1000, status: "pending" },
{ userId: "user-2", totalAmount: 2000, status: "pending" },
{ userId: "user-3", totalAmount: 3000, status: "pending" }
]);
// With context (from Business API action)
const orders = await createBulkOrder([
{ userId: "user-1", totalAmount: 1000, status: "pending" },
{ userId: "user-2", totalAmount: 2000, status: "pending" },
{ userId: "user-3", totalAmount: 3000, status: "pending" }
], this); // Pass 'this' to include session and requestId
Read Functions
get${ModelName}ById(id)
Retrieves a record by its ID. Supports both single ID and array of IDs.
Signature:
get${ModelName}ById(id: string | Array<string>): Promise<Object | Array<Object> | null>
Parameters:
id(String|Array) — Single ID string or array of ID strings
Returns:
- Object — Single record if
idis a string - Array — Array of records if
idis an array - null — If single ID not found (returns empty array for array input if none found)
Behavior:
- Respects soft delete settings (only returns active records if soft delete is enabled)
- Returns normalized data via
getData() - Does not include related/joined data (use
get${ModelName}AggByIdfor that)
Example:
const { getOrderById } = require("dbLayer");
// Get single order
const order = await getOrderById("order-123");
// Get multiple orders
const orders = await getOrderById(["order-123", "order-456", "order-789"]);
get${ModelName}AggById(id)
Retrieves a record with aggregated/joined data from related services via CQRS joins.
Signature:
get${ModelName}AggById(id: string | Array<string>): Promise<Object | Array<Object> | null>
Parameters:
id(String|Array) — Single ID string or array of ID strings
Returns:
- Object — Single record with joined relations if
idis a string - Array — Array of records with joined relations if
idis an array - null — If single ID not found
Behavior:
- Same as
get${ModelName}ByIdbut includes related data from other services - Uses CQRS join mechanism to fetch related data
- Respects soft delete settings
- Returns normalized data with populated relations
Example:
const { getOrderAggById } = require("dbLayer");
// Get order with user and items populated
const order = await getOrderAggById("order-123");
// order.user contains user data
// order.items contains related items
get${ModelName}ListByQuery(query) (deprecated)
Deprecated: Use
get${ModelName}ListByMQueryinstead, which accepts the database-agnostic MScript Query format.
Retrieves multiple records matching a query.
Signature:
get${ModelName}ListByQuery(query: Object): Promise<Array<Object>>
Parameters:
query(Object) — Sequelize or MongoDB query object (format depends on your selected database type)
Returns:
- Array — Array of matching records (empty array if none found)
Behavior:
- Respects soft delete settings (automatically filters
isActive: trueif soft delete is enabled) - Returns normalized data via
getData() - Returns empty array if no matches found (does not throw error)
Query Format Examples:
Sequelize (PostgreSQL, MySQL, etc.):
const { Op } = require("sequelize");
const { getOrderListByQuery } = require("dbLayer");
// Simple query
const orders = await getOrderListByQuery({ status: "paid" });
// Complex query
const orders = await getOrderListByQuery({
status: "paid",
totalAmount: { [Op.gte]: 1000 },
createdAt: { [Op.between]: [startDate, endDate] }
});
MongoDB:
const { getOrderListByQuery } = require("dbLayer");
// Simple query
const orders = await getOrderListByQuery({ status: "paid" });
// Complex query
const orders = await getOrderListByQuery({
status: "paid",
totalAmount: { $gte: 1000 },
createdAt: { $gte: startDate, $lte: endDate }
});
get${ModelName}ByQuery(query) (deprecated)
Deprecated: Use
get${ModelName}ByMQueryinstead, which accepts the database-agnostic MScript Query format.
Retrieves a single record matching a query. Returns the most recently created record if multiple matches exist.
Signature:
get${ModelName}ByQuery(query: Object): Promise<Object | null>
Parameters:
query(Object) — Sequelize or MongoDB query object
Returns:
- Object — First matching record (ordered by
createdAt DESC) or null if not found
Behavior:
- Respects soft delete settings
- Orders results by
createdAt DESCto get the most recent match - Returns null if no match found (does not throw error)
- Returns normalized data via
getData()
Example:
const { getOrderByQuery } = require("dbLayer");
// Get the most recent order for a user
const latestOrder = await getOrderByQuery({ userId: "user-123" });
get${ModelName}StatsByQuery(query, stats) (deprecated)
Deprecated: Use
get${ModelName}StatsByMQueryinstead, which accepts the database-agnostic MScript Query format.
Calculates statistics (count, sum, avg, min, max) on records matching a query.
Signature:
get${ModelName}StatsByQuery(
query: Object,
stats: string | Array<string>
): Promise<number | Object>
Parameters:
query(Object) — Sequelize or MongoDB query objectstats(String|Array) — Stat operation(s) to perform:"count"— Count of matching records"sum(fieldName)"— Sum of a numeric field"avg(fieldName)"— Average of a numeric field"min(fieldName)"— Minimum value of a field"max(fieldName)"— Maximum value of a field
Returns:
- Number — If single stat is requested
- Object — If multiple stats are requested, with keys like
"count","sum-fieldName","avg-fieldName", etc.
Behavior:
- Respects soft delete settings
- Executes all stats in parallel for performance
- Returns single value if one stat requested, object with labeled keys if multiple
Example:
const { getOrderStatsByQuery } = require("dbLayer");
// Single stat
const count = await getOrderStatsByQuery(
{ status: "paid" },
"count"
);
// Returns: 42
// Multiple stats
const stats = await getOrderStatsByQuery(
{ status: "paid" },
["count", "sum(totalAmount)", "avg(totalAmount)", "min(totalAmount)", "max(totalAmount)"]
);
// Returns: {
// count: 42,
// "sum-totalAmount": 125000,
// "avg-totalAmount": 2976.19,
// "min-totalAmount": 100,
// "max-totalAmount": 10000
// }
get${ModelName}ListByMQuery(mQuery)
Retrieves multiple records matching an MScript Query. This is the recommended replacement for get${ModelName}ListByQuery.
Signature:
get${ModelName}ListByMQuery(mQuery: Object): Promise<Array<Object>>
Parameters:
mQuery(Object) — MScript Query object (database-agnostic format, see MScript Query Operators Reference)
Returns:
- Array — Array of matching records (empty array if none found)
Behavior:
- Automatically converts MScript Query to the native database format (Sequelize or MongoDB)
- Respects soft delete settings (automatically filters
isActive: trueif soft delete is enabled) - Returns normalized data via
getData() - Returns empty array if no matches found (does not throw error)
Example:
const { getOrderListByMQuery } = require("dbLayer");
// Simple query
const orders = await getOrderListByMQuery({ status: "paid" });
// Complex query — works the same regardless of database type
const orders = await getOrderListByMQuery({
status: "paid",
totalAmount: { $gte: 1000 },
createdAt: { $between: [startDate, endDate] }
});
// Logical operators
const orders = await getOrderListByMQuery({
$or: [
{ status: "pending" },
{ status: "processing" }
]
});
get${ModelName}ByMQuery(mQuery)
Retrieves a single record matching an MScript Query. Returns the most recently created record if multiple matches exist. This is the recommended replacement for get${ModelName}ByQuery.
Signature:
get${ModelName}ByMQuery(mQuery: Object): Promise<Object | null>
Parameters:
mQuery(Object) — MScript Query object (database-agnostic format, see MScript Query Operators Reference)
Returns:
- Object — First matching record (ordered by
createdAt DESC) or null if not found
Behavior:
- Automatically converts MScript Query to the native database format
- Respects soft delete settings
- Orders results by
createdAt DESCto get the most recent match - Returns null if no match found (does not throw error)
- Returns normalized data via
getData()
Example:
const { getOrderByMQuery } = require("dbLayer");
// Get the most recent order for a user
const latestOrder = await getOrderByMQuery({ userId: "user-123" });
// With operators
const latestPaidOrder = await getOrderByMQuery({
userId: "user-123",
status: { $eq: "paid" }
});
get${ModelName}StatsByMQuery(mQuery, stats)
Calculates statistics (count, sum, avg, min, max) on records matching an MScript Query. This is the recommended replacement for get${ModelName}StatsByQuery.
Signature:
get${ModelName}StatsByMQuery(
mQuery: Object,
stats: string | Array<string>
): Promise<number | Object>
Parameters:
mQuery(Object) — MScript Query object (database-agnostic format, see MScript Query Operators Reference)stats(String|Array) — Stat operation(s) to perform:"count"— Count of matching records"sum(fieldName)"— Sum of a numeric field"avg(fieldName)"— Average of a numeric field"min(fieldName)"— Minimum value of a field"max(fieldName)"— Maximum value of a field
Returns:
- Number — If single stat is requested
- Object — If multiple stats are requested, with keys like
"count","sum-fieldName","avg-fieldName", etc.
Behavior:
- Automatically converts MScript Query to the native database format
- Respects soft delete settings
- Executes all stats in parallel for performance
- Returns single value if one stat requested, object with labeled keys if multiple
Example:
const { getOrderStatsByMQuery } = require("dbLayer");
// Single stat
const count = await getOrderStatsByMQuery(
{ status: "paid" },
"count"
);
// Multiple stats with complex query
const stats = await getOrderStatsByMQuery(
{ status: "paid", totalAmount: { $gte: 100 } },
["count", "sum(totalAmount)", "avg(totalAmount)"]
);
getIdListOf${ModelName}ByField(fieldName, fieldValue, isArray)
Gets a list of IDs for records matching a specific field value. Useful for quick lookups and building relationships.
Signature:
getIdListOf${ModelName}ByField(
fieldName: string,
fieldValue: any,
isArray?: boolean
): Promise<Array<string>>
Parameters:
fieldName(String) — Name of the field to matchfieldValue(Any) — Value to match againstisArray(Boolean, optional) — Iftrue, uses array containment check (for array-type fields)
Returns:
- Array — Array of record IDs matching the criteria
Behavior:
- Respects soft delete settings
- If
isArrayis true, checks iffieldValueis contained in the array field - Throws
NotFoundErrorif no records match (unlike list functions that return empty array) - Only returns IDs, not full records (for performance)
Example:
const { getIdListOfOrderByField } = require("dbLayer");
// Get all order IDs for a user
const orderIds = await getIdListOfOrderByField("userId", "user-123");
// Get all order IDs that contain a specific tag (array field)
const taggedOrderIds = await getIdListOfOrderByField("tags", "urgent", true);
Update Functions
For array field updates using mutation operators ($add, $rem, $addIf) in dataClause, see Array Mutation Syntax Guide.
update${ModelName}ById(id, dataClause, context)
Updates a record by its ID.
Signature:
update${ModelName}ById(
id: string | Object,
dataClause?: Object,
context?: Object
): Promise<Object>
Parameters:
id(String|Object) — Record ID string, or object withidproperty (if object,dataClausecan be omitted and data included in the object)dataClause(Object, optional) — Fields to update (only required ifidis a string)context(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Object — Updated record data (normalized via
getData())
Behavior:
- Throws
NotFoundErrorif record doesn't exist - Respects soft delete settings (only updates active records)
- Automatically indexes updated record in Elasticsearch
- Publishes Kafka events for the update (includes session and requestId from context if provided)
- If
idis an object, extractsidand uses remaining properties asdataClause - Supports array mutation syntax in
dataClausevia$add,$rem,$addIf(see Array Mutation Syntax Guide)
Example:
const { updateOrderById } = require("dbLayer");
// Standard usage (without context)
const updated = await updateOrderById("order-123", {
status: "shipped",
shippedAt: new Date()
});
// With context (from Business API action)
const updated = await updateOrderById("order-123", {
status: "shipped",
shippedAt: new Date()
}, this); // Pass 'this' to include session and requestId
// Using object form
const updated = await updateOrderById({
id: "order-123",
status: "shipped",
shippedAt: new Date()
}, null, this);
update${ModelName}ByIdList(idList, dataClause, context)
Updates multiple records by a list of IDs. All records receive the same update.
Signature:
update${ModelName}ByIdList(
idList: Array<string>,
dataClause: Object,
context?: Object
): Promise<Array<string>>
Parameters:
idList(Array) — Array of record IDs to updatedataClause(Object) — Fields to update (applied to all records)context(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Array — Array of updated record IDs
Behavior:
- Updates all records in the list with the same data
- Respects soft delete settings (only updates active records)
- Automatically indexes all updated records in Elasticsearch
- Publishes Kafka events for each update (includes session and requestId from context if provided)
- Returns IDs (not full records) for performance
- Supports array mutation syntax in
dataClausevia$add,$rem,$addIf(see Array Mutation Syntax Guide)
Example:
const { updateOrderByIdList } = require("dbLayer");
// Mark multiple orders as shipped (without context)
const updatedIds = await updateOrderByIdList(
["order-1", "order-2", "order-3"],
{
status: "shipped",
shippedAt: new Date()
}
);
// With context (from Business API action)
const updatedIds = await updateOrderByIdList(
["order-1", "order-2", "order-3"],
{
status: "shipped",
shippedAt: new Date()
},
this // Pass 'this' to include session and requestId
);
update${ModelName}ByQuery(query, dataClause, context) (deprecated)
Deprecated: Use
update${ModelName}ByMQueryinstead, which accepts the database-agnostic MScript Query format.
Updates all records matching a query.
Signature:
update${ModelName}ByQuery(
query: Object,
dataClause: Object,
context?: Object
): Promise<Array<Object>>
Parameters:
query(Object) — Sequelize or MongoDB query objectdataClause(Object) — Fields to updatecontext(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Array — Array of updated record data (normalized via
getData())
Behavior:
- Updates all records matching the query
- Respects soft delete settings (only updates active records)
- Automatically indexes all updated records in Elasticsearch
- Publishes Kafka events for each update (includes session and requestId from context if provided)
- Returns empty array if no records match
- Supports array mutation syntax in
dataClausevia$add,$rem,$addIf(see Array Mutation Syntax Guide)
Example:
const { Op } = require("sequelize");
const { updateOrderByQuery } = require("dbLayer");
// Mark all pending orders older than 7 days as expired (without context)
const expired = await updateOrderByQuery(
{
status: "pending",
createdAt: { [Op.lt]: sevenDaysAgo }
},
{
status: "expired",
expiredAt: new Date()
}
);
// With context (from Business API action)
const expired = await updateOrderByQuery(
{
status: "pending",
createdAt: { [Op.lt]: sevenDaysAgo }
},
{
status: "expired",
expiredAt: new Date()
},
this // Pass 'this' to include session and requestId
);
update${ModelName}ByMQuery(dataClause, mQuery, context)
Updates all records matching an MScript Query. This is the recommended replacement for update${ModelName}ByQuery.
Signature:
update${ModelName}ByMQuery(
dataClause: Object,
mQuery: Object,
context?: Object
): Promise<Array<Object>>
Parameters:
dataClause(Object) — Fields to updatemQuery(Object) — MScript Query object (database-agnostic format, see MScript Query Operators Reference)context(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Array — Array of updated record data (normalized via
getData())
Behavior:
- Automatically converts MScript Query to the native database format (Sequelize or MongoDB)
- Updates all records matching the query
- Respects soft delete settings (only updates active records)
- Automatically indexes all updated records in Elasticsearch
- Publishes Kafka events for each update (includes session and requestId from context if provided)
- Returns empty array if no records match
- Supports array mutation syntax in
dataClausevia$add,$rem,$addIf(see Array Mutation Syntax Guide)
Example:
const { updateOrderByMQuery } = require("dbLayer");
// Mark all pending orders older than 7 days as expired
const expired = await updateOrderByMQuery(
{
status: "expired",
expiredAt: new Date()
},
{
status: "pending",
createdAt: { $lt: sevenDaysAgo }
}
);
// With context (from Business API action)
const expired = await updateOrderByMQuery(
{
status: "expired",
expiredAt: new Date()
},
{
status: "pending",
createdAt: { $lt: sevenDaysAgo }
},
this
);
Delete Functions
delete${ModelName}ById(id, context)
Deletes a record by its ID. Uses soft delete if enabled, otherwise hard delete.
Signature:
delete${ModelName}ById(id: string | Object, context?: Object): Promise<Object>
Parameters:
id(String|Object) — Record ID string or object withidpropertycontext(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Object — Deleted record data (normalized via
getData())
Behavior:
- Throws
NotFoundErrorif record doesn't exist - If soft delete is enabled: sets
isActive: falseand_archivedAt: timestamp - If soft delete is disabled: permanently deletes from database
- Automatically removes record from Elasticsearch
- Publishes Kafka events for the deletion (includes session and requestId from context if provided)
Example:
const { deleteOrderById } = require("dbLayer");
// Delete an order (without context)
const deleted = await deleteOrderById("order-123");
// With context (from Business API action)
const deleted = await deleteOrderById("order-123", this); // Pass 'this' to include session and requestId
delete${ModelName}ByQuery(query, context) (deprecated)
Deprecated: Use
delete${ModelName}ByMQueryinstead, which accepts the database-agnostic MScript Query format.
Deletes all records matching a query. Uses soft delete if enabled, otherwise hard delete.
Signature:
delete${ModelName}ByQuery(query: Object, context?: Object): Promise<Array<Object>>
Parameters:
query(Object) — Sequelize or MongoDB query objectcontext(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Array — Array of deleted record data (normalized via
getData())
Behavior:
- Deletes all records matching the query
- If soft delete is enabled: sets
isActive: falseand_archivedAt: timestampfor all matching records - If soft delete is disabled: permanently deletes all matching records
- Automatically removes all records from Elasticsearch
- Publishes Kafka events for each deletion (includes session and requestId from context if provided)
- Returns empty array if no records match
Example:
const { Op } = require("sequelize");
const { deleteOrderByQuery } = require("dbLayer");
// Delete all expired orders (without context)
const deleted = await deleteOrderByQuery({
status: "expired",
expiredAt: { [Op.lt]: oneYearAgo }
});
// With context (from Business API action)
const deleted = await deleteOrderByQuery({
status: "expired",
expiredAt: { [Op.lt]: oneYearAgo }
}, this); // Pass 'this' to include session and requestId
delete${ModelName}ByMQuery(mQuery, context)
Deletes all records matching an MScript Query. Uses soft delete if enabled, otherwise hard delete. This is the recommended replacement for delete${ModelName}ByQuery.
Signature:
delete${ModelName}ByMQuery(mQuery: Object, context?: Object): Promise<Array<Object>>
Parameters:
mQuery(Object) — MScript Query object (database-agnostic format, see MScript Query Operators Reference)context(Object, optional) — Context object containingsessionandrequestIdfor event tracking. When called from Business API actions, passthis.
Returns:
- Array — Array of deleted record data (normalized via
getData())
Behavior:
- Automatically converts MScript Query to the native database format (Sequelize or MongoDB)
- Deletes all records matching the query
- If soft delete is enabled: sets
isActive: falseand_archivedAt: timestampfor all matching records - If soft delete is disabled: permanently deletes all matching records
- Automatically removes all records from Elasticsearch
- Publishes Kafka events for each deletion (includes session and requestId from context if provided)
- Returns empty array if no records match
Example:
const { deleteOrderByMQuery } = require("dbLayer");
// Delete all expired orders
const deleted = await deleteOrderByMQuery({
status: "expired",
expiredAt: { $lt: oneYearAgo }
});
// With context (from Business API action)
const deleted = await deleteOrderByMQuery({
status: "expired",
expiredAt: { $lt: oneYearAgo }
}, this);
Query Format Reference
MScript Query Format (Recommended)
The ByMQuery functions accept the unified MScript Query format, which works identically regardless of the underlying database type. See the MScript Query Operators Reference for the full list of supported operators.
// Simple equality
{ status: "active" }
// Comparison operators
{ age: { $gte: 18 } }
{ price: { $between: [100, 500] } }
{ createdAt: { $lt: new Date() } }
// Array operators
{ id: { $in: ["id1", "id2", "id3"] } }
{ tags: { $contains: ["urgent"] } }
// Logical operators
{
$and: [
{ status: "active" },
{ age: { $gte: 18 } }
]
}
{
$or: [
{ status: "pending" },
{ status: "processing" }
]
}
Native Query Formats (for deprecated ByQuery functions)
All deprecated ByQuery functions accept a query parameter in the native format of your selected database type.
Sequelize (PostgreSQL, MySQL, SQLite, etc.)
Use Sequelize query syntax with operators from Op:
const { Op } = require("sequelize");
// Simple equality
{ status: "active" }
// Comparison operators
{ age: { [Op.gte]: 18 } }
{ price: { [Op.between]: [100, 500] } }
{ createdAt: { [Op.lt]: new Date() } }
// Array operators
{ id: { [Op.in]: ["id1", "id2", "id3"] } }
{ tags: { [Op.contains]: ["urgent"] } }
// Logical operators
{
[Op.and]: [
{ status: "active" },
{ age: { [Op.gte]: 18 } }
]
}
{
[Op.or]: [
{ status: "pending" },
{ status: "processing" }
]
}
MongoDB
Use MongoDB query syntax:
// Simple equality
{ status: "active" }
// Comparison operators
{ age: { $gte: 18 } }
{ price: { $gte: 100, $lte: 500 } }
{ createdAt: { $lt: new Date() } }
// Array operators
{ id: { $in: ["id1", "id2", "id3"] } }
{ tags: "urgent" }
// Logical operators
{
$and: [
{ status: "active" },
{ age: { $gte: 18 } }
]
}
{
$or: [
{ status: "pending" },
{ status: "processing" }
]
}
Context Parameter
All create, update, and delete functions accept an optional context parameter as the last argument. The context object should contain:
session(Object, optional) — Current user session datarequestId(String, optional) — Unique identifier for the current request
When to use context:
- In Business API actions: Always pass
thisas the context argument. This automatically providesthis.sessionandthis.requestIdto the utility functions. - In library functions: If you have access to the Business API context, pass it through. Otherwise, you can omit it or pass
null.
Benefits of providing context:
- Kafka events will include session and requestId information
- Better traceability and debugging
- Enables session-aware event processing in downstream services
Example from Business API action:
// Inside a Business API action method
async myAction() {
const { createOrder, updateOrderById } = require("dbLayer");
// Pass 'this' to include session and requestId
const order = await createOrder({
userId: this.session.userId,
totalAmount: 1000
}, this);
await updateOrderById(order.id, { status: "paid" }, this);
}
Best Practices
✅ Do: Use dbLayer Functions with Context
const { getOrderById, updateOrderById } = require("dbLayer");
// Good: Uses utility function with context (from Business API action)
const order = await getOrderById(orderId);
await updateOrderById(orderId, { status: "paid" }, this); // Pass 'this' for context
❌ Don't: Access Models Directly
const { Order } = require("models");
// Bad: Bypasses Elasticsearch sync and Kafka events
const order = await Order.findByPk(orderId);
await order.update({ status: "paid" });
Why?
Direct model access:
- ❌ Bypasses Elasticsearch synchronization
- ❌ Doesn't publish Kafka events
- ❌ May break data consistency
- ❌ Doesn't respect soft delete settings automatically
- ❌ Doesn't normalize data via
getData()
Complete Example
Here's a complete example using multiple utility functions in a library function:
const { Op } = require("sequelize");
const {
getOrderListByQuery,
getOrderStatsByQuery,
updateOrderByIdList,
getIdListOfOrderByField
} = require("dbLayer");
// Example 1: Library function called from Business API action
// If called from a Business API action, receive context and pass it through
module.exports = async function processUserOrders(userId, context = null) {
// Get all active orders for user
const orders = await getOrderListByQuery({
userId: userId,
status: { [Op.in]: ["pending", "processing"] }
});
if (orders.length === 0) {
return { message: "No orders to process" };
}
// Get statistics
const stats = await getOrderStatsByQuery(
{ userId: userId },
["count", "sum(totalAmount)"]
);
// Update all pending orders to processing (with context if provided)
const orderIds = orders.map(o => o.id);
await updateOrderByIdList(orderIds, {
status: "processing",
processedAt: new Date()
}, context); // Pass context through
// Get order IDs for a specific status
const paidOrderIds = await getIdListOfOrderByField("status", "paid");
return {
processed: orders.length,
totalAmount: stats["sum-totalAmount"],
paidOrders: paidOrderIds.length
};
};
// Example 2: Called from Business API action
// In a Business API action, you would call it like:
// LIB.processUserOrders(this.userId, this)
Automatic M2M Edge Functions
All dbLayer utility functions that perform create, update, or delete operations are automatically exposed as M2M-enabled edge functions. This enables other services to call your service's database operations directly using machine-to-machine authentication.
Generated Edge Functions
For each data object, the following M2M edge functions are automatically generated:
m2mCreate{ObjectName}- Wrapscreate{ObjectName}()m2mBulkCreate{ObjectName}- WrapscreateBulk{ObjectName}()m2mUpdate{ObjectName}ById- Wrapsupdate{ObjectName}ById()m2mUpdate{ObjectName}ByQuery- Wrapsupdate{ObjectName}ByQuery()m2mUpdate{ObjectName}ByIdList- Wrapsupdate{ObjectName}ByIdList()m2mDelete{ObjectName}ById- Wrapsdelete{ObjectName}ById()m2mDelete{ObjectName}ByQuery- Wrapsdelete{ObjectName}ByQuery()
Access Methods
Each edge function is accessible via:
- REST API:
POST/PUT/DELETE /m2m/{objectName}/{operation} - Kafka Topic:
{serviceCodename}-m2m-{objectName}-{operation}
Configuration
All automatic M2M edge functions are configured with:
M2MAllowed: true- Requires M2M token authenticationloginRequired: false- No user session required- Both REST and Kafka endpoints enabled
Usage from Other Services
Other services can call these edge functions using the InterService helper module, which is automatically generated for each service:
const { InterService } = require("common-service");
// Create a record in another service
const result = await InterService.callInventoryServicem2mCreateInventoryRecord({
body: {
data: {
productId: "prod-123",
quantity: 10
}
}
});
// Update records by query
const updated = await InterService.callInventoryServicem2mUpdateInventoryRecordByQuery({
body: {
dataClause: { status: "in_stock" },
query: { productId: "prod-123" }
}
});
Multi-Tenant Support
For multi-tenant services, the tenant codename is automatically included in request headers when calling remote M2M edge functions:
mbx-{tenantName}-codename: {tenantCodename}
This ensures that remote services process requests in the correct tenant context.
CRUD Actions Integration
When using CreateCrudAction, CreateBulkCrudAction, UpdateCrudAction, or DeleteCrudAction with a remote data object, the action automatically routes to the appropriate M2M edge function. No manual API calls are required—the inter-service communication is handled transparently.
Summary
| Function | Purpose | Returns |
|---|---|---|
create${ModelName} | Create single record | Object |
createBulk${ModelName} | Create multiple records | Array |
get${ModelName}ById | Get by ID | Object|Array|null |
get${ModelName}AggById | Get by ID with joins | Object|Array|null |
get${ModelName}ListByMQuery | Get multiple by MScript Query | Array |
get${ModelName}ByMQuery | Get single by MScript Query | Object|null |
get${ModelName}StatsByMQuery | Calculate statistics by MScript Query | Number|Object |
getIdListOf${ModelName}ByField | Get IDs by field | Array |
update${ModelName}ById | Update by ID | Object |
update${ModelName}ByIdList | Update multiple by IDs | Array (IDs) |
update${ModelName}ByMQuery | Update by MScript Query | Array |
delete${ModelName}ById | Delete by ID | Object |
delete${ModelName}ByMQuery | Delete by MScript Query | Array |
get${ModelName}ListByQuery | (deprecated) Get multiple by native query | Array |
get${ModelName}ByQuery | (deprecated) Get single by native query | Object|null |
get${ModelName}StatsByQuery | (deprecated) Calculate statistics by native query | Number|Object |
update${ModelName}ByQuery | (deprecated) Update by native query | Array |
delete${ModelName}ByQuery | (deprecated) Delete by native query | Array |
All functions automatically handle Elasticsearch indexing, Kafka event publishing, and soft delete logic. Always prefer the ByMQuery variants for new code — they use the database-agnostic MScript Query format and work identically across all supported database types.
Last updated Mar 30, 2026
Built with Documentation.AI