mongo-aggregation-utils
v1.2.8
Published
Reusable MongoDB aggregation helpers for Node.js and TypeScript
Maintainers
Readme
MongoDB Aggregation Utilities
A collection of reusable TypeScript helper functions for building MongoDB aggregation pipeline stages.
These utilities follow the DRY principle, making $lookup, $unionWith, $dateToString, $arrayElemAt, and other MongoDB expressions easier to use.
📚 Functions
1. lookupDataFromCollection
Performs a $lookup to join data from another collection and optionally extracts a specific element or the entire array.
Parameters
collection(string) – Foreign collection name.localField(string) – Local field from input documents.
Format can be:"fieldName"→ Returns the first element."fieldName:2"→ Returns the 2nd element."fieldName:all"→ Returns all elements."fieldName:unwind"→ Returns unwind elements.
exportField?(string) – Output field name (defaults tolocalField).pipeline?(Array) – Optional aggregation pipeline inside$lookup.foreignField?(string) – Foreign field to match against (defaults to_id).unwindField?(string) – unwind perticular field in your array.
Behavior
- If
"all"is passed, returns only the$lookupstage and got all array data. - If
"unwind"is passed, returns$lookup+$unwindto extract that element. - If a number is passed, returns
$lookup+$setto extract that element. - Defaults to extracting the first element.
Returns
[
{ $lookup: { from, localField, foreignField, as, pipeline } },
{ $set: { [outputField]: { $arrayElemAt: [`$${as}`, index] } } },
{ $unwind: field },
];Sample Data
const orders = [
{
userId: "user1",
productId: "product1",
},
];
const users = [
{
_id: "user1",
name: "User Name",
},
];Finding User Orders
db.users.aggregate([
...lookupDataFromCollection("orders", "_id", "userData", [], "userId"),
]);Returns
[
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "userId",
as: "userData",
},
},
{ $set: { userId: { $arrayElemAt: [`$userId`, 0] } } },
];- Description: Joins the
orderscollection with theuserscollection based on matching_idfromusersanduserIdfromorders. - Result: Returns each user with one matching order.
db.users.aggregate([
...lookupDataFromCollection("orders", "_id", "userData:all",[],"userId"),
]);Returns
[
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "userId",
as: "userData",
},
},
];- Description: Joins
orderswithusersand returns all matching orders for each user. - Result: Returns each user with an array of all their orders.
db.users.aggregate([
...lookupDataFromCollection("orders", "_id", "userData:3", [], "userId"),
]);Returns
[
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "userId",
as: "userData",
},
},
{ $set: { userId: { $arrayElemAt: [`$userId`, 2] } } },
];- Description: Joins
orderswithusersand retrieves the 3rd order (index-based) for each user. - Result: Returns each user with only the order at 3 object.
Finding User Data from Orders
db.orders.aggregate([...lookupDataFromCollection("users", "userId")]);Returns
[
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userId",
},
},
{ $set: { userId: { $arrayElemAt: [`$userId`, 0] } } },
];- Description: Joins
userswithordersusinguserIdfromordersto match_idinusers. - Result: Returns each order with the user object embedded.
db.orders.aggregate([...lookupDataFromCollection("users", "userId:2")]);Returns
[
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userId",
},
},
{ $set: { userId: { $arrayElemAt: [`$userId`, 1] } } },
];- Description: Retrieves the 2nd user (index-based) from the matched user array in the order document.
- Result: Returns each order with the 2nd user object embedded.
db.orders.aggregate([...lookupDataFromCollection("users", "userId:all")]);Returns
[
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userId",
},
},
];- Description: Retrieves all user objects starting from index
2in the matched array of users for each order. - Result: Returns each order with an array of alll users.
Note
- In most real-world cases, one order is linked to only one user.
- The
lookupDataFromCollectionhelper is flexible enough to:- Return a single match
- Return all matches
- Return matches starting from or at a specific index
- This makes it easier to handle both 1-to-1 and 1-to-many relationships in aggregation queries.
- You didnt passed export field then local field also consider as export field
- foreignField priority rules
- If you pass a foreignField, it takes the highest priority.
- If you not passed foreignField, _id will be used as the foreignField.
- export FIeld primary rules
- If you passed exportField, it takes the highest priority
- If you not passed exportField , lcoalField will be used as the exportField
2. extractArrayElementByIndex
Extracts an element from an array at the specified index using MongoDB’s $arrayElemAt operator.
Parameters
field(string) – The array field to extract from.count(number, default = 0) – 1-based index of the element to retrieve. Internally,count - 1is used to match MongoDB’s 0-based indexing.
Returns
{
$arrayElemAt: [field, index];
}3. switchCase
Creates a single case condition for use inside a $switch expression.
Parameters
conditionField(string) – The field or value to compare.matchValue(string) – The value to match.resultField(string) – The value to return if the condition is true.
Returns
{
case: { $eq: [conditionField, matchValue] },
then: resultField
}4. isFieldEquals
Creates an $eq comparison between a field and a value.
Parameters
field(string) – The field name.value(any) – The value to compare.
Returns
{
$eq: [`$${field}`, value];
}5. concatString
Concatenates three fields or values into a single string, separated by " - ".
Parameters
field1(string) – First field name.field2(string) – Second field name (converted to string).field3(string) – Third field name.
Returns
{
$concat: [
`$${field1}`,
" - ",
{ $toString: `$${field2}` },
" - ",
`$${field3}`,
];
}6. isRequiredCollectionData
Checks if each given array field has at least one element using $expr and $size.
Parameters
...field(Array) – Field names to validate.
Returns
[
{ $expr: { $gt: [{ $size: "$fieldName" }, 0] } },
...
]7. unionWith
Creates a $unionWith stage to combine results from another collection.
Parameters
collection(string) – Collection name.pipeline?(Array) – Optional aggregation pipeline for the unioned collection.
Returns
{
$unionWith: {
coll: collection,
pipeline: pipeline || []
}
}8. formatDateToString
Formats a date field into a string in the YYYY-MM-DD format using $dateToString.
Parameters
field(string) – The date field to format.
Returns
{
$dateToString: {
format: '%Y-%m-%d',
date: `$${field}`
}
}9. isDataMatch
Builds a $match stage to filter documents by a main field and optional additional conditions.
Parameters
key(string) – Field name to match.value(any) – Value to match.object?(Record<string, any>) – Optional extra match conditions.
Returns
[
{
$match: {
[key]: value,
...object, // Optional extra conditions
},
},
];10. calculateSum
Creates a MongoDB $sum aggregation expression for summing the values of a specific field.
Parameters
sumField(string) – The name of the field whose values should be summed.
Returns
{
$sum: `$${sumField}`;
}11. unwindData
Creates a MongoDB $unwind stage to deconstruct an array field into multiple documents.
Parameters
field(string) – The name of the array field to unwind.
Returns
{
$unwind: `$${field}`;
}