Fast, lightweight library to transform objects to mongo update instructions using operators and dot notation.
Heavily inspired by npm::Mongo Dot Notation.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
const instructions = $.flatten({
firstName: 'John',
contact: { phone: '874-478-1254' },
lastUpdate: $.$currentDate()
})
/*
const instructions = {
$currentDate: {
lastUpdate: { $type: 'date' }
},
$set: {
'firstName': 'John',
'contact.phone': '874-478-1254'
}
}
*/
- Transform objects to
mongo
update instructions- supports embedded documents
- supports mongo types (
ObjectID
,Int32
etc.)
- Full support of
mongo
update operatorsField
update operatorsArray
update operatorsBitwise
update operators
- Supports
Deno 1.1.3
and above - No unecessary dependencies on
mongo
Using $.flatten
and operators to transform to mongo update instructions.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
const MongoClient = require('mongodb').MongoClient
const url = 'mongodb://localhost:27017/db'
const users = (await MongoClient.connect(url)).db.collection('users')
const updateData = {
comments: $.$push('Logged in.').$each().$slice(-100),
env: 'demo',
login: {
date: $.$currentDate()
},
analytics: {
visits: $.$inc()
},
account: {
createdOn: $.$setOnInsert(new Date()),
blocked: $.$unset(),
attempts: 0,
logins: $.$inc()
}
}
await users.update({ _id: 1 }, $.flatten(updateData))
Without mongo-dot-notation
update instructions should look like:
// ...
const updateData = {
$set: {
'env': 'demo',
'account.attempts': 0
},
$push: {
'comments': {
'$each': ['Logged in.'],
'$slice': -100
}
}
$currentDate: {
'login.date': 'date'
},
$inc: {
'analytics.visits': 1,
'account.logins': 1,
},
$unset: {
'account.blocked': ''
},
$setOnInsert: {
'account.createdOn': new Date()
}
}
await users.update({ _id: 1 }, updateData)
$ deno test
Use .flatten()
to transform objects:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
const instructions = $.flatten({
account: {
name: 'hero'
}
})
// { '$set': { 'account.name': 'hero' } }
Checks if a given value is a mongo-dot-notation
operator:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.isOperator(1) // false
$.isOperator({}) // false
$.isOperator($.$set(10)) // true
See below the list of all supported mongo update opertors.
See mongo $inc.
The $inc
operator increments a field by a specified value. If no value is provided, defaults to 1.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
visits: $.$inc(5) // increment current visits value by 5
})
// { '$inc': { 'visits': 5 } }
See mongo $mul.
Multiplies the value of a field by a number. (Supported in mongo >= 2.6)
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
price: $.$mul(0.75) // multiply current price value by 0.75
})
// { '$mul': { 'price': 0.75 } }
See mongo $rename.
The $rename
operator updates the name of a field.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
nmae: $.$rename('name') // rename nmae field to name
})
// { '$rename': { 'nmae': 'name' } }
See mongo $setOnInsert.
Assigns value to field only when the document is inserted (when an update operation is with upsert:true
). (Supported in mongo >= 2.4)
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
db.collection('users').update(
{ _id: 1 },
$.flatten({
createdOn: $.$setOnInsert(new Date()) // sets createdOn field only when document is inserted
}),
{ upsert: true })
// { '$setOnInsert': { 'createdOn': new Date() } }
See mongo $set.
The $set
operator replaces the value of a field with the specified value.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
name: $.$set('Mike')
})
// { '$set': { 'name': 'Mike' } }
The $set
is an implicit operator, meaning if an object is passed to $.flatten
, it will navigate through own and embedded document fields and apply $set.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
name: 'Mike',
contactDetails: {
email: '[email protected]'
}
})
// {
// '$set': {
// 'name': 'Mike',
// 'contactDetails.email': '[email protected]'
// }
// }
The $set
operator could also be used to update an embedded document entirely:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
name: 'Mike',
// contactDetails is updated to a new document
contactDetails: $.$set({
email: '[email protected]'
})
})
// {
// '$set': {
// 'name': 'Mike',
// 'contactDetails': { email: '[email protected]' }
// }
// }
See mongo $unset.
The $unset
operator deletes a particular field.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
comments: $.$unset(), // remove field from document
history: $.$unset()
})
// { '$unset': { 'comments': '', 'history': '' } }
See mongo $min.
The $min
updates the value of the field to a specified value if the specified value is less than the current value of the field.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
low: $.$min(200) // update low to 200 if current low value is greater than 200
})
// { '$min': { 'low': 200 } }
See mongo $max.
The $max
operator updates the value of the field to a specified value if the specified value is greater than the current value of the field.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
high: $.$max(450) // update high to 450 if current high value is less than 450
})
// { '$max': { 'high': 450 } }
See mongo $currentDate.
The $currentDate
operator sets the value of a field to the current date, either as a Date or a Timestamp.
If type is not specified, uses Date by default.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
lastUpdate: $.$currentDate()
})
// { '$currentDate': { 'lastUpdated': { '$type': 'date' } } }
To set as a timestamp, use:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
lastUpdate: $.$currentDate('timestamp')
})
// { '$currentDate': { 'lastUpdated': { '$type': 'timestamp' } } }
Also, for timestamp an alias operator is defined in mongo-dot-notation
:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
lastUpdate: $.$timestamp()
})
// { '$currentDate': { 'lastUpdated': { '$type': 'timestamp' } } }
See mongo $ (update).
The positional $
operator identifies an element in an array to update without explicitly specifying the position of the element in the array.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
db.students.update(
{ _id: 1, grades: 80 }, // match all elements from grades array where value equals to 80
$.flatten({
grades: $.$().$set(82) // for matched elements, update value to 82
})
)
// { $set: { "grades.$" : 82 } }
In order to update the matched document's field:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
db.students.update(
{ _id: 1, 'grades.grade': 80 },
$.flatten({
grades: $.$('std').$set(1.5)
})
)
// { $set: { "grades.$.std" : 1.5 } }
The positional $
operator is chainable with all mongo supported update fields.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
db.students.update(
{ _id: 1, grades: 80 },
$.flatten({
grades: $.$().$mul(0.1) // multiplies matched array element by 0.1
})
)
// { $mul: { "grades.$" : 0.1 } }
Can also be used to update an array element by a given index:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
grades: $.$(0).$set(100)
})
// { $set: { "grades.0" : 0.1 } }
Same, when updating the element's field:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
months: $.$('5.avgTemp').$set(25.7)
})
// { $set: { "months.5.avgTemp" : 25.7 } }
See mongo $addToSet.
The $addToSet
operator adds a value to an array unless the value is already present, in which case $addToSet does nothing to that array.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
values: $.$addToSet(5)
})
// { '$addToSet': { 'values': 5 } }
To add each value from a given array:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
values: $.$addToSet([7, 1, 4]).$each()
})
// { '$addToSet': { 'values': { '$each': [7, 1, 4] } } }
See mongo $pop.
The $pop
operator removes the first or last element of an array. Pass $pop a value of -1 to remove the first element of an array and 1 to remove the last element in an array.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
values: $.$pop() // removes by default last element
})
// { '$pop': { 'values': 1 } }
To remove first element from the array:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
values: $.$pop(-1)
})
// { '$pop': { 'values': -1 } }
There are chainable .first()
and .last()
methods defined:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
indexes: $.$pop().first(),
scores: $.$pop().last(),
})
// { '$pop': { 'indexes': -1, scores: 1 } }
See mongo $pullAll.
The $pullAll
operator removes all instances of the specified values from an existing array.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
values: $.$pullAll([0, 1])
})
// { '$pullAll': { 'values': [0, 1] } }
See mongo $pull.
The $pull
operator removes from an existing array all instances of a value or values that match a specified condition.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
values: $.$pull(7)
})
// { '$pull': { 'values': 7 } }
If an array is provided, implicitly applies $in
operator:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
values: $.$pull([0, 1])
})
// { '$pull': { 'values': { '$in': [0, 1] } } }
See mongo documentation for conditions.
See mongo $push.
The $push
operator appends a specified value to an array. Can also be used to slice and sort the array.
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
grades: $.$push({ grade: 'A' })
})
// { '$push': { 'grades': { grade: 'A' } } }
To push several values, chain with .$each()
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
grades: $.$push([{ grade: 'A' }, { grade: 'B' }]).$each()
})
// {
// '$push': {
// 'grades': {
// '$each': [{ grade: 'A' }, { grade: 'B' }]
// }
// }
// }
To push values at a specific position use .$position()
(requires the use of .$each(). Supported in mongo >= 2.6)
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
// insert as a first element in the array
$.flatten({
grades: $.$push({ grade: 'A' }).$each().$position(0)
})
// {
// '$push': {
// 'grades': {
// '$each': [{ grade: 'A' }],
// '$position': 0
// }
// }
// }
To slice the array, use .slice()
(requires the use of .$each(). Supported in mongo >= 2.6)
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
// insert the element and limit to last 10 values
$.flatten({
grades: $.$push({ grade: 'A' }).$each().$slice(-10)
})
// {
// '$push': {
// 'grades': {
// '$each': [{ grade: 'A' }],
// '$slice': -10
// }
// }
// }
To sort the array, use .sort()
(requires the use of .$each(). Supported in mongo >= 2.4)
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
// insert the element and sorts descending by grade
$.flatten({
grades: $.$push({ grade: 'A' }).$each().$sort({ grade: -1})
})
// {
// '$push': {
// 'grades': {
// '$each': [{ grade: 'A' }],
// '$sort': { grade: -1}
// }
// }
// }
Multiple instructions can be chained:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
// insert the element, sorts descending by grade
// and slices only first 10 values
$.flatten({
grades: $.$push({ grade: 'A' }).$each().$sort({ grade: -1}).$slice(10)
})
// {
// '$push': {
// 'grades': {
// '$each': [{ grade: 'A' }],
// '$sort': { grade: -1},
// '$slice': 10
// }
// }
// }
In case the array needs only to be sorted and/or sliced, mongo-dot-notation
defines aliases:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
grades: $.$sort({ grade: 1 }), // sames as $.push([]).$each().$sort({ grade: 1 })
scores: $.$slice(10), // sames as $.push([]).$each().$slice(1)
values: $.$sort().$slice(-5) // sames as $.push([]).$each().$sort().$slice(-5)
})
See mongo $bit.
The $bit
operator performs a bitwise update of a field. The operator supports bitwise AND, bitwise OR, and bitwise XOR (i.e. exclusive or) operations.
Note XOR is supported in mongo >= 2.6
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
owner: $.$bit().$and(7) // performs a bitwise AND
user: $.$bit().$or(1) // performans a bitwise OR
group: $.$bit().$xor(5) // performs a bitwise XOR
})
// {
// '$bit': {
// 'owner': { and: 7 },
// 'user': { or: 1 },
// 'group': { xor: 5 },
// }
// }
Following aliases are defined in mongo-dot-notation
:
import * as $ from 'https://deno.land/x/mongo-dot-notation/mod.ts';
$.flatten({
owner: $.$and(7), // same as $.$bit().$and(7)
user: $.$or(1), // same as $.$bit().$or(1)
group: $.$xor(5), // same as $.$bit().$xor(5)
})