Mongoose Id Assigner (IA)
A Mongoose Plugin. Easily Manage fields that need an id(unique value) on your mongoose model. This plugin does the work of generating, incrementing, and assigning those values(unique) to those fields.
This plugin assigns values base on your configurations, be it MongoDB's ObjectId
, UUID
, Number Increments
, String Generators
or you provide your custom nextIdFunction
.
It creates a collection with name id_assigner
that store the nextId
for a configured field. This only happens if you have fields configured with type String
or Number
. As ObjectId
and UUID
can be generated locally unique, they do not use this collection for assigning values.
This is the perfect tool if you wish to work with discriminators
and have _id
field(and/or other fields) values different amongst the discriminators instances. See examples below for demonstration.
Table of Content
- Installation
- Basic Usage
- Examples
- Working with Discriminators
- Strain Test
- TypeDefinitions
- Contributions
- License
Installation
yarn add mongoose-id-assigner
or
npm install mongoose-id-assigner
If you wish to use UUIDs
FieldTypes, then you need to add this package, uuid.
yarn add uuid
Basic Usage
You could create the plugin from the MongooseIdAssigner
Constructor, which returns a instance which you could use to query nextIds
.
from constructor(schema: Schema, options: AssignerPluginOptions): MongooseIdAssigner
...const ExampleIA = exampleSchema options;exampleModel = mongoose; // always call the initialise, to ensure assigner initialised before calling getNextId// assigners are always auto initialised on every first saveawait ExampleIA;await ExampleIA; // nextId...
Alternatively you have the plugin setup by calling the static plugin
method.
static plugin(schema: Schema, options: AssignerPluginOptions): MongooseIdAssigner
...exampleSchema;...
AssignerPluginOptions
Parameter | Type | Description |
---|---|---|
modelName | String(Required) | Name of the Model your are working with. If discriminators, then provide baseModel Name. |
fields | AssignerFieldsConfigMap (Optional) | The configuration Map of the fields you want the assigner to assign ids to. If undefined, then plugin assigns ids to _id field, (ObjectId). |
discriminators | DiscriminatorConfigMap (Optional) | An Object with key being a discriminatorName and value a Configuration Map for fields on that discriminator that need unique values. Any discriminator without a fieldConfig will use that of the baseModelk |
Points to Note
-
At every Network Assigner init(i.e Assigner with Number, String FieldConfigTypes), the Assigner(for a Model) refreshes and syncs with the db stored options. Take example micro-service cluster, the last app to init always gives most recent field configs, if the db have a field that is not in the most recent field config, it is auto dropped. Therefore always make sure all your micro-service clusters start up with same fieldsConfigs as the last to start rewrites the db and only keeps nextIds.
-
Always Setup plugin before creating Mongoose Model for that schema.
-
Always set FieldConfig Type to reflect schema's path Type, that is if schema Type is
Number
, then useNumber
FieldConfigType. SeeExampleSchema
below with its associated IdAssigners.
Examples
Lets create our Mongoose Schema.
// schema.js We would be reusing this schema for brevity (clone); const ExampleSchema = _id: String photoId: Number emailId: String personId: String uuidField: Buffer uuidFieldString: String uuidFieldBuffer: Buffer objectIdField: mongooseSchemaTypesObjectId;
Configuration methods
Method 1: Quick Config, Intended for usage with schema.plugin(...)
. It initialises only when the first document is about to be saved.
Options Type: AssignerPluginOptions
.
const options: AssignerPluginOptions = modelName: 'ExampleModel' fields: // if no _id field config, assigner auto adds _id field with type = "ObjectId" uuidFieldString: 'UUID' ; ExampleSchema; // Saving the first doc triggers the IdAssigner initialisation for this model.const ExampleModel = mongoose; const doc = await ExampleModel; console ---> '5b57a1d929239e59b4e3d7f3' // schema field type is Stringconsole ---> '7729e2e0-8f8b-11e8-882d-2dade78bb893'
Method 2: Using the MongooseIdAssigner
constructor, it takes in the schema
as first parameter, then options as second, returning IdAssigner Instance.
You can now initialise and use the IdAssigner instance to request nextId
s for particular fields.
Options Type: AssignerOptions
.
Working with Discriminators
You may have a discriminator Instance and want to have different id Types, or fields on one discriminator need to be autogenerated uniquely, here is an example;
; ; ; ; ;; ;; ;;;;; console.logcharacter._id ---> '5b59d98617e2edc57ede52b8'console.logcharacter.someId ---> 4444console.logawait CharacterIA.getNextId'someId' ---> 4445 console.logperson._id ---> '5b59d98617e2edc57ede52ba'console.logperson.someId ---> 4445console.logperson.license ---> '786-TSJ-000' console.logdroid._id ---> '48db52c0-90df-11e8-b43b-ffe3d317727b'console.logdroid.someId ---> 4446console.logdroid.make ---> '18Y4433'console.logawait CharacterIA.getNextId'make', 'Droid' ---> '18Y4434' console.logperson._id ---> '5b59d98617e2edc57ede52bb'console.logperson1.someId ---> 4447console.logperson1.license ---> '786-TSJ-001'console.logawait CharacterIA.getNextId'license', 'Person' ---> '786-TSJ-002' console.logdroid1._id ---> 'eb185fb0-90df-11e8-800d-dff50a2d22a3' console.logdroid1.someId ---> 4448console.logdroid1.make ---> '18Y4434'
WIP
NextId It may arise that you need to query and use the nextId to at the front-end. In this case, you just need to
get an instance of the Assigner, then use the getNextId
method. It is async method as it queries for Number
and String
cases.
Strain test
- Performs the task below on a locally hosted db instance.
- On CI/CD environment, tests ran using mongodb-memory-server, on v3.4, v3.6, v4.0 and v4.2 on node v12, v10, v8
// using ts :);; describe'MongooseIdAssigner',;
TypeDefinitions
/** * If Options does not contain fields(AssignerFieldsConfigMap), * Then setup assigner for _id field, does not use network */ /** * fieldConfig = string, then nextId = string, default incrementer, * fieldConfig = number, then nextId = number, incrementBy = 1 * fieldConfig = boolean(true), then fieldType = ObjectId * fieldConfig = GUID | UUID, then use UUID v1 */ /** * A map of discriminatorName(modelName) and its own AssignerFieldsConfigMap */ /** * * @property * order doesn't matter but all those keys must be present, no 1, 3, 4, 6. * If noSpace is true, then on holdTimeout, that nextId will be use on any newly saving doc, else nextId discarded * * @property * @property * @property * @property */;
CONTRIBUTIONS
If you find a bug, do well to create an issue so we fix things up in a flash. Have an awesome new feature to add to library, feel free to open a PR
NextIdFunctions (Incrementer)
If you have a superb nextIdFunction, and you wish it can be added to the list of nextIdFunctions, feel free to drop a pull request and submit your function.