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

Type:StoreMongoDefaultExport
Namespace:@jerni/store-mongo
Extends:Object

Properties

makeStore:
(MongoDbStoreConfig) => MongoDbStore

create a MongoDbStore instance from given configuration

Examples
file: journey/my-mongo-store.js
/* ... */
await makeMongoDbStore({
name: 'MyServices',
url: 'mongodb://localhost:27017',
dbName: 'my_service_dev',
models: [clients, profiles],
});
Model:
Class<MongoDbReadModel>

Encapsulate projection logic for a MongoDB Collection

readPipeline:
([MongoDbReadModel], PipelineOperation[]) => MongoDBAggregationResults

Declaratively read data from a collection during projection stage

Examples
file: example-count-with-condition.js
/* 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 [ /* ... */ ];
}
file: example-lookup-different-collection.js
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 [ /* ... */ ];
}