Transform objects to MongoDB update instructions.
import { flatten, $timestamp, $unset } from 'mongo-dot-notation';
const user = flatten({
firstName: 'Alice',
contact: { phone: '874-478-1254' },
address: {
primary: {
state: 'NY',
nr: 42,
},
},
});
Sets user
to:
{
"$set": {
"firstName": "Alice",
"contact.phone": "874-478-1254",
"address.primary.state": "NY",
"address.primary.nr": 42
}
}
npm install mongo-dot-notation
- Supports all MongoDB update operators
- Field update operators
- Array update operators
- Bitwise update operators
- No
npm
dependency onmongo
- Written in TypeScript
- Type definitions for all exported functions
- Supports flattening and updating array elements by index
import { flatten, $inc, $currentDate, $push, $setOnInsert } from 'mongo-dot-notation';
const review = {
// Add a comment and keep only the last ten ones
comments: $push('Like it!').$each().$slice(-10),
rating: 10,
counters: {
// increment the `total` by one
total: $inc(),
},
details: {
// set only if the document is inserted
createdOn: $setOnInsert(new Date()),
// set to current date as a mongo Date
updatedOn: $currentDate(),
},
};
// Provided reviews is a MongoDB collection
await reviews.updateOne(reviewId, flatten(review), { upsert: true });
import { flatten } from 'mongo-dot-notation';
const user = {
phones: [
{
number: '123-456-789',
primary: true,
},
{
number: '789-012-345',
},
],
};
// Provided users is a MongoDB collection
await users.updateOne(userId, flatten(user, { array: true }));
The above user
object is flattened to:
{
"phones.0.number": "123-456-789",
"phones.0.primary": true,
"phones.1.number": "789-012-345"
}
import { flatten, $, $inc } from 'mongo-dot-notation';
const student = {
grades: $().$inc(),
};
// Finds the element with value 80 in the "grades" array
// and increments it by one.
student.updateOne(
{ _id: 1, grades: 80 },
flatten(student) // { $inc: { "grades.$" : 1 } }
);
The position operator supports updating a nested document:
import { flatten, $, $inc } from 'mongo-dot-notation';
const student = {
grades: $('value').$inc(),
};
// Finds the document with "value" field equal to 80 in the "grades" array
// and increments it by one.
student.updateOne(
{ _id: 1, grades: 80 },
flatten(student) // { $inc: { "grades.$.value" : 1 } }
);
To update all elements in a array, use all positional operator:
import { flatten, $, $inc } from 'mongo-dot-notation';
const student = {
grades: $('[]').$inc(),
};
// Increment all grades by one
student.updateOne(
{ _id: 1 },
flatten(student) // { $inc: { "grades.$[]" : 1 } }
);
Similarly, updating nested documents:
import { flatten, $, $inc } from 'mongo-dot-notation';
const student = {
grades: $('[].values').$inc(),
};
// Increment all grades' values by one
student.updateOne(
{ _id: 1 },
flatten(student) // { $inc: { "grades.$[].values" : 1 } }
);
import { flatten, $, $mul } from 'mongo-dot-notation';
const student = {
grades: $('[element]').$mul(9),
};
// Multiply by ten all grades that are below 9
student.updateOne(
{ _id: 1 },
flatten(student), // { $mul: { "grades.$[element]" : 10 } }
{ arrayFilters: [{ element: { $lte: 9 } }] }
);
Similarly, updating nested documents:
import { flatten, $, $mul } from 'mongo-dot-notation';
const student = {
grades: $('[element].value').$mul(9),
};
// Multiply by ten all grades that are below 9
student.updateOne(
{ _id: 1 },
flatten(student), // { $mul: { "grades.$[element].value" : 10 } }
{ arrayFilters: [{ 'element.value': { $lte: 9 } }] }
);
Using positional operator to merge fields into the matched element:
import { flatten, $, $inc, $currentDate } from 'mongo-dot-notation';
const student = {
grades: $().merge({
class: '101',
prof: 'Alice',
value: $inc(),
date: $currentDate(),
}),
};
flatten(student);
Result:
{
"$set": {
"grades.$.class": "101",
"grades.$.prof": "Alice"
},
"$inc": {
"grades.$.value": 1
},
"$currentDate": {
"grades.$.date": { "$type": "date" }
}
}
To update all elements, use $('[]')
instead of $()
in the above example.
Using positional operator to update nested arrays:
import { flatten, $, $mul } from 'mongo-dot-notation';
const student = {
grades: $().merge({
questions: $('[]').merge({
value: $mul(100),
}),
}),
};
flatten(student);
Calling flatten(student)
results in:
{
"$mul": {
"grades.$.questions.$[].value": 100
}
}
See the end-to-end tests file for more examples.
Table of contents
The following options are available:
Option | Description |
---|---|
array |
(default false ) if true, arrays will be flattened and their indexes will be used as keys. |
skipEmptyObjects |
(default false ) if true, empty objects are ignored and removed from the flattened result. |
Example:
flatten({ rules: [{ value: 7 }] }, { array: true });
// { $set: { 'rules.0.value': 7 } }
flatten({ rules: [{ value: 7 }] }, { array: false });
// { $set: { 'rules': [{value: 7}] } }
flatten({ left: { x: 1 }, right: {} }, { skipEmptyObjects: true });
// { $set: { 'left.x': 1 } }
flatten({ left: { x: 1 }, right: {} }, { skipEmptyObjects: false });
// { $set: { 'left.x': 1, 'right': {} } }
$flatten<T>(obj: T, options?: Options)
Transforms a given object into the MongoDB's update instructions.
Param | Description |
---|---|
obj |
(required) the input object to transform |
options |
(optional) additional options, see Options |
Example:
flatten({
firstName: 'Alice',
contact: { phone: '874-478-1254' },
address: {
primary: {
state: 'NY',
nr: 42,
},
},
});
isOperator<T>(obj: T): boolean
Checks if a given object is an operator.
Param | Description |
---|---|
obj |
(required) the input object to check |
Example:
isOperator($set(1)); // true
isOperator({}); // false
$currentDate(type?: 'date' | 'timestamp')
Param | Description |
---|---|
type |
(default date ) sets to MongoDB's Date or Timestamp type. |
Sets the value of a field to the current date.
Example:
flatten({
createdOn: $currentDate(),
});
$timestamp()
Sets the value of a field to the current date as a MondoDB's Timestamp type.
This function is an alias for $currentDate('timestamp')
.
Example:
flatten({
updatedOn: $timestamp(),
});
$inc<T>(value?: T)
Increments a field by a specified value.
Param | Description |
---|---|
value |
(default 1) increment value |
Example:
flatten({
visits: $inc(),
clicks: $inc(5),
});
$min<T>(value: T)
Updates the value of the field to a specified value if the specified value is less than the current value of the field.
Param | Description |
---|---|
value |
(required) min value |
Example:
flatten({
score: $min(100),
});
$max<T>(value: T)
Updates the value of the field to a specified value if the specified value is greater than the current value of the field.
Param | Description |
---|---|
value |
(required) max value |
Example:
flatten({
score: $max(0),
});
$mul<T>(value?: T)
Multiplies the value of a field by a number.
Param | Description |
---|---|
value |
(default 1) multiply factor |
Example:
flatten({
score: $mul(2.5),
});
$rename(field: string)
Updates the name of a field.
Param | Description |
---|---|
field |
(required) new field name |
Example:
flatten({
profile: {
first_name: $rename('firstName'),
},
});
$set<T>(value: T)
Replaces the value of a field with the specified value.
This is an implicit operator, but could be useful when an entire object should be replaced.
Param | Description |
---|---|
value |
(required) replacement value |
Example:
// Replaces the address object entirely rather than just
// updating the "city" field.
flatten({
address: $set({ city: 'NY' }),
profile: { name: 'Alice' },
});
// Outputs:
// {
// "$set": {
// "address": { "city": "NY" },
// "profile.name": "Alice"
// }
// }
$setOnInsert<T>(value: T)
Assigns the specified value to the field when { upsert: true }
operation is used and
results in a new document being created. If the update operation does not result in an insert,
does nothing.
Param | Description |
---|---|
value |
(required) the value to set on document creation |
Example:
flatten({
logging: {
createdOn: $setOnInsert(new Date()),
},
});
$unset()
Deletes the specified field from a document.
Example:
flatten({
resetPassword: $unset(),
});
$(field?: number | string)
The positional operator identifies an element or multiple elements matching a given query condition to be updated in an array.
Param | Description |
---|---|
field |
(optional) when empty - performs the update on array's element; when a number or a string starting with a number, specifies the index of the element to update or its field; when starts with "[]" or "[query]" , specifies that this is an all positional operator; |
Example:
// Sets to 7 first element that matches the update query
$().$set(7);
// Increment by one the first element's `score` field that matches the update query
$('score').$inc(1);
// Multiplies all elements by two
$('[]').$mul(2);
// Ensures all elements in array are positive
$('[].score').$max(0);
// Find all `grades` documents that have the `std` lower than seven
// and increment their `grade` by ten.
collection.updateOne(criteria, flatten({ grades: $('[element].grade').$inc(10) }), {
arrayFilters: [{ 'element.std': { $lt: 7 } }],
});
See update nested arrays for examples using $().merge
.
$addToSet<T>(value: T | T[])
Adds a value to an array unless the value is already present.
To add multiple values, chain with $each
operator.
Param | Description |
---|---|
value |
(required) the value to add to the set |
Note that while $addToSet([1, 2])
adds the entire array as single element,
$addToSet([1, 2]).$each()
adds 1 and 2 as separate elements.
Example:
// add just one element
flatten({ permissions: $addToSet('admin') });
// add multiple elements
flatten({ permissions: $addToSet(['read', 'write']).$each() });
$pop(value?: -1 | 1)
Removes the first or last element of an array
Param | Description |
---|---|
value |
(default 1) specify -1 to remove the first element, 1 to remove the last element |
Example:
// remove the first element from the array
flatten({ grades: $pop(-1) });
// equivalent to:
flatten({ grades: $pop().first() });
// remove the last element from the array
flatten({ scores: $pop(1) });
// equivalent to:
flatten({ scores: $pop().last() });
$pull<T>(value: T | T[])
Removes from an existing array all instances of a value or values that match a specified condition. Unlike the $pullAll operator, this operator can be used to remove all instances that match a query.
Param | Description |
---|---|
value |
(required) the value(s) to remove or the condition to match for removed elements |
Example:
// remove all instances of the value `0` and `1` from the array;
// same as using $pullAll
flatten({ scores: $pull([0, 1]) });
// remove all instances lower than or equal to `3`
flatten({ scores: $pull({ $lte: 3 }) });
// remove all documents with the field `name` equal to `Test`
flatten({ users: $pull({ name: { $eq: 'Test' } }) });
$push<T>(value?: T | T[])
Appends a specified value to an array.
Can be chained with .$slice()
, .$sort()
and .$position()
modifiers to specify how the array should be updated.
The order in which additional operators are chained doesn't matter, so that $push().$each().$slice().$sort()
is the same as
$push().$each().$sort().$slice()
.
Param | Description |
---|---|
value |
(optional) the value(s) to append to the array |
Example:
// append one element
flatten({ scores: $push(1) });
// append multiple elements
flatten({ scores: $push([1, 2, 3]).$each() });
// append an element and update to leave only the last ten
flatten({ scores: $push(7).$each().$slice(-10) });
// append an element and update to leave only the last ten sorted by value
flatten({ scores: $push(7).$each().$sort(1).$slice(-10) });
// append an element at position three in the array
flatten({ scores: $push(7).$each().$position(2) });
$pullAll<T>(value: T | T[])
Removes all instances of the specified values from an existing array.
Param | Description |
---|---|
value |
(required) the value(s) to remove from the array |
Example:
// remove all instances of the value `1` and `2` from the array
flatten({ score: $pullAll([1, 2]) });
// remove all instances of the value `0`
flatten({ score: $pullAll(0) });
$slice(count: number)
Limits the number of array elements.
Alias for $push().$each().$slice()
.
Param | Description |
---|---|
count |
(required) number of elements to take |
Example:
// leave only the first 3 elements
flatten({ grades: $slice(3) });
// leave only the last element
flatten({ grades: $slice(-1) });
// empty the array
flatten({ grades: $slice(0) });
$sort<T>(specification?: T)
Orders the elements of an array.
Alias for $push().$each().$sort()
.
Param | Description |
---|---|
specification |
(default 1) sort specification |
Example:
// sort ascending
flatten({ scores: $sort(1) });
// sort descending
flatten({ scores: $sort(-1) });
// sort ascending an array of documents with `name` field
flatten({ users: $sort({ name: 1 }) });
$bit()
Performs a bitwise update of a field. Should be chained with a logical operator.
Example:
flatten({
admin: $bit().$and(7),
read: $bit().$or(4),
write: $bit().$xor(3),
});
$and<T>(value: T)
Uses a bitwise and operation to update a field.
Alias for $bit().$and()
.
Example:
flatten({
admin: $and(7),
});
$or<T>(value: T)
Uses a bitwise or operation to update a field.
Alias for $bit().$or()
.
Example:
flatten({
read: $or(4),
});
$xor<T>(value: T)
Uses a bitwise xor operation to update a field.
Alias for $bit().$xor()
.
Example:
flatten({
write: $xor(3),
});