pipemongo
v0.6.5
Published
Utilities for MongoDB pipeline aggregation
Downloads
47
Maintainers
Readme
pipemongo
Utility for creating composable MongoDB operators
!!! Beware: this is a work in progress !!!
Installation
npm i pipemongo --save
Built-in operator functions
Pipemongo comes with built-in operator functions corresponding to base MongoDB operators that are ready to use out of the box. To put one of these operator functions to work just import and use:
const {
eq,
or,
and,
not,
...
} = require('pipemongo');
const myAggregationPipeline = [
{
_id: '$myId',
onlyOneThingIsTrue: and(
or(
eq('$thing1', true),
eq('$thing2', true)
),
not(
and(
eq('$thing1', true),
eq('$thing2', true)
)
)
)
},
out('outCollection')
];
Additionally, pipemongo comes with some common extensions of those base operator functions. These are available right alongside the base operator functions, so just import and use:
const {
xor,
isTrue
...
} = require('pipemongo');
const myAggregationPipeline = [
{
_id: '$myId',
onlyOneThingIsTrue: xor(
isTrue('$thing1'),
isTrue('$thing2')
)
},
out('outCollection')
];
85+ built-in operator functions are ready to import and use out of the box. You can check out all available built-in operator function here
Roll your own operator functions
Need a more complex operator function than is available in the built-in module? No problem. Use the pipemongo cli that comes with the pipemongo package to reliably define and roll your own custom, composable operator functions.
To start, run mkdir pipemongo-config
to create a pipemongo configuration directory in the root of your project. The pipemongo cli will peek into this directory for operator module configuration files to generate pipemongo operators and roll them directly into the pipemongo package.
Pipemongo cli will create modules for json files in the pipemongo-config directory. So we can create a module config file with appropriate configuration properties to produce custom operator functions:
{
"name": "myModule",
"description": "Provides some really cool custom MongoDB operators",
"dependencies": [
{
"module": "comparison",
"fns": [ "ne" ]
}
],
"fns": [
{
"name": "notBuggy",
"args": [
{
"name": "val",
"type": "mixed",
"comment": "Any expression that resolves to a string"
}
],
"returnValue": "ne(val, 'buggy')"
}
]
}
And that's it!
Run node ./node_modules/pipemongo/cli build all
to roll your custom operator function into the pipemongo package, import and put it to use:
const {
notBuggy
} = require('pipemongo').myModule;
const myAggregationPipeline = [
{
_id: '$myId',
isOK: notBuggy('$mightBeBuggy')
},
out('outCollection')
];
All custom modules defined properly in pipemongo-config will be available under the module name in the top level pipemongo package object.
FAQ
So whenever node_modules gets deleted, my custom operator functions are gone too?
Yup! Since custom operator functions defined in the pipemongo-config directory are rolled directly into the pipemongo package under the node_modules directory, obliterating the node_modules directory also deletes the custom operator functions.
But have no fear! Once pipemongo is installed again, just run node ./node_modules/pipemongo/cli build all
and you'll be right back where you started.
This also means that if you don't add pipemongo-config to your .gitignore, anyone that clones the repository and installs pipemongo can recreate all of your custom operator functions with the node ./node_modules/pipemongo/cli build all
cli build all command.
Isn't using a string for the returnValue pretty limiting?
Yes! That's the point! Because pipemongo config files are JSON files and the returnValue must be a string, you're encouraged to keep the returnValue short. If a returnValue string takes multiple lines, it may be a good candidate to split into two composable operator functions.
Instead of:
{
// ...module info
fns: [
{
"name": "theBeatlesOrTheBeeGees",
// ...function info
"returnValue": "or(eq(val, 'John Lennon|Paul McCartney|George Harrison|Ringo Starr'), eq(val, 'Barry Gibb|Robin Gibb|Maurice Gibb'))"
}
]
}
Try:
{
// ...module info
fns: [
{
"name": "theBeatlesOrTheBeeGees",
// ...function info
"returnValue": "or(theBeatles(val), theBeeGees(val))"
},
{
"name": "theBeatles",
// ... function info
"returnValue": "eq(val, 'John Lennon|Paul McCartney|George Harrison|Ringo Starr')"
},
{
"name": "theBeeGees",
// ... function info
"returnValue": "eq(val, 'Barry Gibb|Robin Gibb|Maurice Gibb')"
},
]
}
Which makes further composition that much easier later on:
{
// ...module info
fns: [
// ...existing functions
{
"name": "theBeatlesOrTheBeachBoys",
// ...function info
"returnValue": "or(theBeatles(val), theBeachBoys(val))"
},
{
"name": "theBeachBoys",
// ... function info
"returnValue": "eq(val, 'Brian Wilson|Mike Love|Al Jardine|David Marks|Bruce Johnston')"
}
]
}