SparrowQL computed function example
ralphievolt opened this issue · comments
Based on the blog here
https://medium.com/vazco/dynamic-aggregations-with-sparrowql-dfeb133821e7
There’s also
computed
, which is an advanced feature, designed to handle a $group phase.
however the feature cannot be seen in the manual to creat the $group
operators
Indeed, it's not yet documented. Again, here's the tests we'll analyze [1] and [2].
In general, computed
has two modes: mapper (used to make $project
phases) and non-mapper (default, to make $group
phases). Let's start with mapper (2):
const pipeline = build({
computed: {
mapper: {
mapper: true,
required: [`${collectionA.collectionName}.i`, `${collectionA.collectionName}.n`],
result: ['y'],
perform: relative => ({
_id: relative(`${collectionA.collectionName}._id`, true),
y: relative(`${collectionA.collectionName}.x`, true)
})
}
},
sort: {[makeComputed('mapper.y')]: 1},
start: collectionA.collectionName
});
How it works:
mapper: true
states, that$project
phase will be used,required
defines a list of fields, which are needed to compute this phase,result
lists all outputs, which may be used later inquery
,sort
, etc.,perform
is a function, which has to return the body of given phase (here: projection),relative(name, isPath)
function is useful to make sure, that theperform
works for eachstart
collectionisPath
parameter prefixes returned path with$
, which is sometimes needed, for example in$ifNull
or at the top level in projection phase.
Now the non-mapper (1):
const pipeline = build({
computed: {
stats: {
required: [`${collectionA.collectionName}.i`, `${collectionA.collectionName}.n`],
result: ['sum'],
perform: relative => ({
_id: relative(`${collectionA.collectionName}.i`, true),
sum: {$sum: '$n'}
})
}
},
sort: {[makeComputed('stats.sum')]: 1},
query: {[`${collectionA.collectionName}.i`]: {$ne: 'spam'}},
start: collectionA.collectionName
});
Important difference:
- no
mapper: true
implies$group
phase.
If it's working for you, @ralphievolt, and that is completely clear, I'll write it down and include in the docs (or link it at least for now).