jerni
a framework to build data-driven products from the ground up

module: @jerni/store-mongo/readPipeline

Declaratively read data from a collection during projection stage

Summary

type: Function

Parameters

model
: MongoDBReadModel

(optional) if specified, this is the model to run aggregation pipeline against. The current model is aggregated otherwise

pipeline
: PipelineOperation[]

an array of MongoDB pipeline stages

returns

Usages

// Declaratively read data from a collection during projection stage
const readPipeline = require("@jerni/store-mongo/readPipeline");
/* transform function for Profiles model */
function transform(event) {
const results = readPipeline([
{ $match: { age: { $gte: 18 } } },
{ $count: 'adultsCount' },
]);
// if $match doesn't find any document, next stage will receive empty stream,
// thus $count stage will just return empty stream as well
const count = result.length === 0 ? 0 : result[0].adultsCount;
// decide what to do depending on the value of count
if (count > 3) {
return [ /* ... */ ];
}
return [ /* ... */ ];
}
// Declaratively read data from a collection during projection stage
const readPipeline = require("@jerni/store-mongo/readPipeline");
const ProductModel = new Model(/* ... */);
const OrderModel = new Model({
name: "orders",
version: "1",
transform(event) {
// readPipeline can run conditionally
if (event.type === "ORDER_MADE") {
const { product_ids, order_id } = event.payload;
// readPipeline can run repetatively in a loop
const unitPrices = product_ids.map(id => {
// readPipeline can run agaist other models as well
return readPipeline(ProductModel, [
{ $match: { id } }, // query a specific product
{ $project: { unitPrice: 1 } } // only get its price
])
});
// NOTE: don't do this in production, use one pipeline to map/reduce for better performance
const total = unitPrices.reduce((a, b) => a + b);
return [{
insertOne: {
id: order_id,
products: product_ids,
total
}
}]
}
}
})
/* transform function for Profiles model */
function transform(event) {
const results = readPipeline([
{ $match: { age: { $gte: 18 } } },
{ $count: 'adultsCount' },
]);
// if $match doesn't find any document, next stage will receive empty stream,
// thus $count stage will just return empty stream as well
const count = result.length === 0 ? 0 : result[0].adultsCount;
// decide what to do depending on the value of count
if (count > 3) {
return [ /* ... */ ];
}
return [ /* ... */ ];
}