Version 7.2.0
This release adds support for MongoDB's mapReduce
operation thanks to a brilliant PR by @RagibHasin. It supports both inline mapReduce and reducing into a typed Iridium collection. It also includes a number of improvements to Iridum's documentation and some regression tests to help avoid situations like we saw in #73.
Using MapReduce
Inline Reduce
Inline reductions are great for once-off operations where you do not wish to persist the results to a collection. It allows you to provide a map
and reduce
function and will return the resulting documents that leave the reduce
function.
interface MySourceDoc {
_id: string;
group_key: string;
value: number;
}
@Iridium.Collection("source")
class MySourceModel extends Iridium.Instance<MySourceDoc, MySourceModel> {
_id: string;
group_key: string;
value: number;
}
const core = new Iridium.Core("mongodb://localhost:27017")
await core.connect()
const source = new Iridium.Model<MySourceDoc, MySourceModel>(core, MySourceModel);
const result = await source.mapReduce({
map: function() {
emit(this.group_key, this.value);
},
reduce: function(key, values) {
return Array.sum(values);
}
}, { out: "inline" });
result.forEach(item => {
console.log(`group '${item._id}': ${item.value}`);
});
Reduce into a Collection
In situations where you require more control over the documents you receive from mapReduce
(performing transforms etc) you can use the @Iridium.MapReduce
decorator function on an instance class and provide that to the mapReduce
method call. This will allow you to retroactively access the results of the mapReduce
operation in the specified @Iridium.Collection
.
interface MySourceDoc {
_id: string;
group_key: string;
value: number;
}
@Iridium.Collection("source")
class MySourceModel extends Iridium.Instance<MySourceDoc, MySourceModel> {
_id: string;
group_key: string;
value: number;
}
interface MyReducedDoc {
_id: string;
value: number;
}
@Iridium.Collection("reduced")
@Iridium.MapReduce<MySourceDoc, string, number>(function() {
emit(this.group_key, this.value);
}, function(key, values) {
return Array.sum(values);
})
class MyReducedModel extends Iridium.Instance<MyReducedDoc, MyReducedModel> {
_id: string;
value: number;
}
const core = new Iridium.Core("mongodb://localhost:27017")
await core.connect()
const source = new Iridium.Model<MySourceDoc, MySourceModel>(core, MySourceModel);
const reduced = new Iridium.Model<MyReduceDoc, MyReduceModel>(core, MyReduceModel);
await source.mapReduce(reduced, { out: "replace" })
await reduced.find().forEach(item => {
console.log(`group '${item._id}': ${item.value}`);
});