• Stars
    star
    427
  • Rank 101,680 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated about 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Elegant MongoDB driver for Node.js.

Mongolass

NPM version Build status Dependency Status License Downloads

Elegant MongoDB driver for Node.js.

Installation

$ npm i mongolass --save

Usage

const Mongolass = require('mongolass')
const mongolass = new Mongolass()
mongolass.connect('mongodb://localhost:27017/test')// const mongolass = new Mongolass('mongodb://localhost:27017/test')

const User = mongolass.model('User')

User
  .find()
  .select({ name: 1, age: 1 })
  .sort({ name: -1 })
  .exec()
  .then(console.log)
  .catch(console.error)

Or use optional schema:

const Mongolass = require('mongolass')
const Schema = Mongolass.Schema
const mongolass = new Mongolass('mongodb://admin:123456@localhost:27017/admin', {
  dbName: 'testdb'
})

const UserSchema = new Schema('UserSchema', {
  name: { type: 'string', required: true },
  age: { type: 'number', default: 18 }
})
const User = mongolass.model('User', UserSchema)

/*
equal to:
const User = mongolass.model('User', {
  name: { type: 'string', required: true },
  age: { type: 'number', default: 18 }
})
will create inner schema named `UserSchema`.
*/

User
  .insertOne({ name: 'nswbmw', age: 'wrong age' })
  .exec()
  .then(console.log)
  .catch(console.error)
/*
{ TypeError: ($.age: "wrong age") ✖ (type: number)
    at Model.insertOne (/Users/nswbmw/Desktop/test/node_modules/mongolass/lib/query.js:101:16)
    at Object.<anonymous> (/Users/nswbmw/Desktop/test/app.js:21:4)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3
  validator: 'type',
  path: '$.age',
  actual: 'wrong age',
  expected: { type: 'number', default: 18 },
  schema: 'UserSchema',
  model: 'User',
  op: 'insertOne',
  args: [ { name: 'nswbmw', age: 'wrong age' } ],
  pluginName: 'MongolassSchema',
  pluginOp: 'beforeInsertOne',
  pluginArgs: [] }
*/

ObjectId schema:

'use strict'

const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')

const Post = mongolass.model('Post', {
  author: { type: Mongolass.Types.ObjectId }
}, { collName: 'post' })

Post.insertOne({ author: '111111111111111111111111' })
  .then(function () {
    return Post.find({ author: '111111111111111111111111' })
  })
  .then(console.log)
/*
[ { _id: 57caed24ecda6ffb15962591,
    author: 111111111111111111111111 } ]
 */

NB: You can pass collName as collection name.

API

Same as node-mongodb-native.

Mongolass vs Mongoose

知乎:从零开始写一个 Node.js 的 MongoDB 驱动库


I've been using Mongoose for years, it's great but complex sucks, so i wrote Mongolass. Mongolass is not simply mimicking Mongoose, but rather draw on the advantages of mongoose redesigned the architecture. Mongolass has some exciting features different from Mongoose:

  1. Pure Schema. In Mongoose, Schema and Model and Entity are confused.

Schemas not only define the structure of your document and casting of properties, they also define document instance methods, static Model methods, compound indexes and document lifecycle hooks called middleware.

In Mongolass, Schema is only used for defining the structure of your document and casting of properties, Model used for retrievaling data from mongodb and register plugins, Entity(as result) is plain object. Schema is also optional.

  1. Awesome plugin system. Mongoose plugin system is not strong enough, eg: .pre, .post, use async next(). In Mongolass, we can register a plugin for Model or global mongolass instance. like:
User.plugin('xx', {
  beforeFind: function (...args) {},// or function return Promise
  afterFind: async function (result, ...args) {
    console.log(result, args)
    ...
  },
  // afterFind: async function (result, ...args) {
  //   console.log(result, args)
  //   ...
  // }
})

Above added two hook functions for User, when User.find().xx().exec() is called, the execution order is as follows:

beforeFind(handle query args) -> retrieve data from mongodb -> afterFind(handle query result)

Mongolass's plugins could be substituted for Mongoose's (document instance methods + static Model methods + plugins).

  1. Detailed error informations. see usage.
User
  .insertOne({ name: 'nswbmw', age: 'wrong age' })
  .exec()
  .then(console.log)
  .catch(console.error)
/*
{ TypeError: ($.age: "wrong age") ✖ (type: number)
    at Model.insertOne (/Users/nswbmw/Desktop/test/node_modules/mongolass/lib/query.js:105:16)
    at Object.<anonymous> (/Users/nswbmw/Desktop/test/app.js:23:4)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:598:3
  validator: 'type',
  actual: 'wrong age',
  expected: { type: 'number' },
  path: '$.age',
  schema: 'UserSchema',
  model: 'User',
  op: 'insertOne',
  args: [ { name: 'nswbmw', age: 'wrong age' } ],
  pluginName: 'MongolassSchema',
  pluginOp: 'beforeInsertOne',
  pluginArgs: [] }
*/

According to the error instance, esay to know age expect a number but got a string, from error stack know it's broken on app.js:23:4 and the operator is Model.insertOne.

Schema

see another-json-schema, support default and required.

required

const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')

const User = mongolass.model('User', {
  name: { type: 'string', required: true },
  age: { type: 'number', default: 18 }
})

;(async function () {
  await User.insert({ age: 17 })
})().catch(console.error)

Output:

{ TypeError: ($.name: undefined)  (required: true)
    at Model.insert (/Users/nswbmw/Desktop/test/node_modules/mongolass/lib/query.js:101:16)
    at /Users/nswbmw/Desktop/test/app.js:10:14
    at Object.<anonymous> (/Users/nswbmw/Desktop/test/app.js:11:3)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)
  validator: 'required',
  path: '$.name',
  actual: undefined,
  expected: { type: 'string', required: true },
  schema: 'UserSchema',
  model: 'User',
  op: 'insert',
  args: [ { age: 17 } ],
  pluginName: 'MongolassSchema',
  pluginOp: 'beforeInsert',
  pluginArgs: [] }

default

const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')

const User = mongolass.model('User', {
  name: { type: 'string', required: true },
  age: { type: 'number', default: 18 },
  createdAt: { type: Mongolass.Types.Date, default: Date.now }
})

;(async function () {
  await User.insert({ name: 'nswbmw' })
  const user = await User.findOne({ name: 'nswbmw' })
  console.log(user)
  // { _id: 5a530c5d39d9a4eb3aa57856, name: 'nswbmw', age: 18, createdAt: 2019-01-10T09:50:26.831Z }
})()

Types

  • string
  • number
  • boolean
  • Mongolass.Types.ObjectId
  • Mongolass.Types.String
  • Mongolass.Types.Number
  • Mongolass.Types.Date
  • Mongolass.Types.Buffer
  • Mongolass.Types.Boolean
  • Mongolass.Types.Mixed

What's difference between number and Mongolass.Types.Number ? number only check type, Mongolass.Types.Number will try to convert value to a number, if failed then throw error.

Plugins

mongolass.plugin(pluginName, hooks)// register global plugin
User.plugin(pluginName, hooks)// register model plugin

example:

const moment = require('moment')
const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User')

mongolass.plugin('addCreatedAt', {
  beforeInsert: function (format) {
    console.log('beforeInsert', this._op, this._args, format)
    // beforeInsert insert [ { firstname: 'san', lastname: 'zhang' } ] YYYY-MM-DD
    this._args[0].createdAt = moment().format(format)
  }
})

User.plugin('addFullname', {
  afterFindOne: function (user, opt) {
    console.log('afterFindOne', this._op, this._args, opt)
    // afterFindOne findOne [] { sep: '-' }
    if (!user) return user
    user.fullname = user.firstname + opt.sep + user.lastname
    return user
  },
  afterFind: async function (users, opt) {
    console.log('afterFind', this._op, this._args, opt)
    // afterFind find [ { firstname: 'san' } ] { sep: ' ' }
    if (!users.length) return users
    return users.map(user => {
      user.fullname = user.firstname + opt.sep + user.lastname
      return user
    })
  }
})

;(async function () {
  // when use await, .exec() is omissible.
  await User.insert({ firstname: 'san', lastname: 'zhang' }).addCreatedAt('YYYY-MM-DD')
  console.log(await User.findOne().addFullname({ sep: '-' }))
  // { _id: 5850186544c3b82d23a82e45,
  //   firstname: 'san',
  //   lastname: 'zhang',
  //   createdAt: '2016-12-13',
  //   fullname: 'san-zhang' }
  console.log(await User.find({ firstname: 'san' }).addFullname({ sep: ' ' }))
  // [ { _id: 5850186544c3b82d23a82e45,
  //     firstname: 'san',
  //     lastname: 'zhang',
  //     createdAt: '2016-12-13',
  //     fullname: 'san zhang' } ]
})().catch(console.error)

NOTE: Different order of calling plugins will output different results. The priority of Model's plugins is greater than global's.

example:

const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User')

User.plugin('add2', {
  afterFindOne: function (user) {
    if (!user) return user
    user.name = `${user.name}2`
    return user
  }
})
User.plugin('add3', {
  afterFindOne: async function (user) {
    if (!user) return user
    user.name = `${user.name}3`
    return user
  }
})

;(async function () {
  await User.insert({ name: '1' })
  console.log(await User.findOne().add2().add3())
  // { _id: 58501a8a7cc264af259ca691, name: '123' }
  console.log(await User.findOne().add3().add2())
  // { _id: 58501a8a7cc264af259ca691, name: '132' }
})().catch(console.error)

see mongolass-plugin-populate.

Built-in plugins

Mongolass has some built-in plugins, only for find and findOne.

example:

const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User')

;(async function () {
  await User.insert({ name: '1' })
  await User.insert({ name: '2' })
  const result = await User
    .find()
    .skip(1)
    .limit(1)
  console.log(result)
  // [ { _id: 58501c1281ea915a2760a2ee, name: '2' } ]
})().catch(console.error)

Test

$ npm test (coverage 100%)

License

MIT

More Repositories

1

N-blog

《一起学 Node.js》
JavaScript
15,348
star
2

node-in-debugging

《Node.js 调试指南》
6,379
star
3

N-chat

使用 Express + Socket.IO 搭建的多人聊天室
JavaScript
1,159
star
4

N-club

使用 Koa + MongoDB + Redis 搭建论坛系统
JavaScript
516
star
5

node-wechat

Node.js 微信公众平台 API
JavaScript
356
star
6

koa-mongo

MongoDB middleware for koa, support connection pool.
JavaScript
146
star
7

N-weibo

使用 Meteor 搭建微博网站
JavaScript
145
star
8

douyu-mac-app

逗鱼直播 Mac app
124
star
9

micro-scraper

Node.js 爬虫示例 (for:百度百科)
JavaScript
108
star
10

config-lite

A super simple & flexible & useful config module.
JavaScript
89
star
11

N-drifter

使用 Redis 搭建漂流瓶服务器
JavaScript
82
star
12

paloma

An angular-like MVC framework, based on koa@2 & bottlejs.
JavaScript
70
star
13

everblog

Evernote + Blog = EverBlog
JavaScript
55
star
14

another-json-schema

Another JSON Schema validator, simple & flexible & intuitive.
JavaScript
48
star
15

koa-scheme

koa-scheme is a parameter validation middleware for koa.
JavaScript
47
star
16

thunder-vip

Get available thunder vips.
JavaScript
47
star
17

koa-ip

Ip filter middleware for koa, support whitelist and blacklist.
JavaScript
38
star
18

appoint

Another Promise implementation. Inspired by [lie](https://github.com/calvinmetcalf/lie).
JavaScript
29
star
19

koa-await-breakpoint

Add breakpoints around `await` expression especially for koa@2.
JavaScript
27
star
20

cpu-memory-monitor

CPU & Memory Monitor, auto dump.
JavaScript
27
star
21

koa-frouter

File/Folder as `path`, another router middleware for koa.
JavaScript
24
star
22

koa-router-cache

Router cache middleware for koa.
JavaScript
22
star
23

koa-toobusy

Toobusy middleware for koa.
JavaScript
21
star
24

koa-redis-pool

Redis middleware for koa, support connection pool.
JavaScript
19
star
25

proxy-hot-reload

Node.js application hot reload with `Proxy`.
JavaScript
19
star
26

node-wechat-expression

微信内置表情代码包
JavaScript
16
star
27

kless

A framework inspired by FaaS, based on `koa`.
JavaScript
16
star
28

koa-res

Format koa's respond json.
JavaScript
15
star
29

douban-movie-top250

豆瓣电影 Top 250 爬虫
JavaScript
15
star
30

cli-chat

Cli-chat. Try it out ~
JavaScript
15
star
31

puppeteer-debug

puppeteer-debug
JavaScript
15
star
32

koa-await-breakpoint-jaeger

jaeger for koa-await-breakpoint.
JavaScript
13
star
33

koa-errorhandler

Error handler middleware for koa.
JavaScript
11
star
34

repl2

Load third-party modules into REPL from `.noderc`.
JavaScript
11
star
35

objectid-to-timestamp

objectId to timestamp, in `ms`.
JavaScript
10
star
36

co-cache

Cache result in redis for GeneratorFunction or function that return a Promise.
JavaScript
10
star
37

sublime-NodeRequire

A Sublime Text plugin for requiring modules (for: Node.js).
Python
9
star
38

ioredis-timeout

Add timeout to ioredis
JavaScript
9
star
39

npm-user-downloads

List npm user all modules download counts.
JavaScript
9
star
40

etcd-proxy

Node.js service registry and discovery on top of etcd.
JavaScript
9
star
41

node-oschina

Node.js 版开源中国 API
JavaScript
9
star
42

co-ejs

Koa ejs view render middleware.
JavaScript
8
star
43

enml2html

parse ENML to HTML
JavaScript
8
star
44

markdown-css

add CSS to Markdown
JavaScript
7
star
45

alfred-httpstatuses

Alfred workflow for [httpstatuses.com](https://httpstatuses.com)
JavaScript
7
star
46

node-domains

List of domains, include com, org ...
JavaScript
6
star
47

koa-version

Mounting app by version to different router.
JavaScript
6
star
48

puppeteer-extra-plugin-proxy2

Add proxy for puppeteer `page`, support `http`, `https`, `socks`. Based on puppeteer-page-proxy.
JavaScript
6
star
49

node-category

Files/Directorys categorization tool.
JavaScript
5
star
50

alfred-cnode

alfred workflow for cnodejs.org
Python
5
star
51

everblog-adaptor-hexo

Hexo adaptor for [everblog](https://github.com/everblogjs/everblog).
JavaScript
5
star
52

koa-use

Overwrite koa's `use()`, add `Array` support.
JavaScript
5
star
53

npm-package-downloads

Get packages download counts.
JavaScript
4
star
54

ioredis-ratelimit

Generic ratelimit tool on top of ioredis.
JavaScript
4
star
55

koa-router-schema

Schema validate middleware for [koa-router](https://github.com/alexmingoia/koa-router).
JavaScript
4
star
56

koa-forward-request

Forward request for koa.
JavaScript
4
star
57

koa-router-validator

Validator middleware for [koa-router](https://github.com/alexmingoia/koa-router).
JavaScript
4
star
58

chrome-cnode-notifier

CNode notifier extension for Chrome.
JavaScript
4
star
59

node-linereader

Reading a url or file line by line.
JavaScript
3
star
60

node-hump

convert a string(like: hello-world) to hump-style string(to: helloWorld)
JavaScript
3
star
61

everblog-theme-koa

[koa](http://koajs.com/) theme for everblog.
CSS
3
star
62

rust-NAPI-fibonacci

A fibonacci demo of [rust-node-api](https://github.com/jupp0r/node-api).
Rust
3
star
63

rename_github_title

For someone who open soooooo many github repos in chrome.
JavaScript
3
star
64

enml2text

parse ENML to TEXT
JavaScript
2
star
65

koa-raven

raven middleware for koa.
JavaScript
2
star
66

create-paloma-app

create paloma app easily.
JavaScript
2
star
67

co-slowlog

slowlog for GeneratorFunction or function that return a Promise.
JavaScript
2
star
68

paloma-benchmark

Paloma benchmark
JavaScript
2
star
69

validator-it

Just validate it, based on [validator](https://github.com/chriso/validator.js).
JavaScript
2
star
70

rust-napi-demo

rust-napi-demo
C
2
star
71

everblog-theme-spa

SPA theme for [everblog-adaptor-spa](https://github.com/everblogjs/everblog-adaptor-spa).
CSS
2
star
72

path-to-mongodb

Express style path to mongodb query.
JavaScript
1
star
73

stackoverflow-retime

StackOverflow Retime
JavaScript
1
star
74

alfred-jsonbeautifier

Beautify JSON input, output to clipboard.
1
star
75

everblog.io

HTML
1
star
76

bushishiren.com

不是诗人官网
HTML
1
star
77

everblog-adaptor-spa

SPA adaptor for [everblog](https://github.com/everblogjs/everblog).
JavaScript
1
star
78

is-gmail

Check if an given email is google apps email.
JavaScript
1
star
79

paloma-examples

Examples using paloma
JavaScript
1
star
80

airwallex-node

Airwallex Nodejs SDK
JavaScript
1
star
81

qs-mongodb

Parse URL querystring to MongoDB query.
JavaScript
1
star
82

koa-slowlog

slowlog for koa, based on [co-slowlog](https://github.com/nswbmw/co-slowlog).
JavaScript
1
star
83

node-nana

node nanananana ~ node nanananana ~
JavaScript
1
star
84

sublime-open-require

Open file in sublime, specifically for Node.js's `require()`.
Python
1
star
85

grafana-to-elk

Telegraf(StatsD) + InfluxDB + Grafana + ELK
JavaScript
1
star
86

koa-format

A koa middleware format `this.request` and `this.response`.
JavaScript
1
star