Welcome to MQ-Adonisjs-Models!
MQ-Models is a set of base models for MQ's Team server.
MQ-Models runs on Adonisjs 4, lucid-mongo.
It rewrites the relational definitions in models and functions to extend and query the mongoDB more easily.
Lucid mongo: https://github.com/duyluonglc/lucid-mongo
Install
npm install adonis-mqmodel
in Models file: use use('adonis-mqmodel') as BaseModel.
const Model = use('adonis-mqmodel')
class User extends Model {
.....
}
in start/app.js add command:
...
const commands = [
'adonis-mqmodel/Commands/commands.js'
]
....
Using
Relations
This package support relations like lucid-mongo:
- belongsTo
- belongsToMany
- hasMany
- hasManyThrough
- hasOne
- morphMany
- morphTo
- morphOne
- embedsOne
- embedsMany
- referMany
Addition relations
Use relationships to declare relationships, which are structured as:
static get relationships() {
return {
<relationName1>:{
<relatedName1>: [<Model Related 1>, <localField>, <ForeginField>],
<relatedName2>: [<Model Related 2>, <localField>, <ForeginField>],
},
<relationName2>:{
<relatedName3>: [<Model Related 3>, <localField>, <ForeginField>],
<relatedName4>: [<Model Related 4>, <localField>, <ForeginField>, <custom params (optional)>],
},
}
}
Relations between tables will be created automatically, but in the case of too complex data, it is necessary to declare custom params to create data constraints.
Example:
const Model = use('adonis-mqmodel')
class User extends Model {
static get relationships() {
return {
hasMany: {
tokens: ['App/Models/Token', '_id', 'userId']
},
referMany: {
roles: ['App/Models/Role', '_id', 'roleIds'],
permissions: ['App/Models/Permission', '_id', 'permissionIds', {
$lookup: {
from: 'permissions',
let : {
localField: `$roles.permisstions`
},
pipeline: [
{$match:{
$expr: {$in: ["$_id", "$$localField"]}
}}
],
as: 'permissions'
}
}]},
}
}
}
.....
}
Schema
Schema is the structure of the database. It is used to query more easily.
The library automatically generates schemas or you can create them manually.
Automatic creation using command:
adonis mqmodel schema: create
To be able to create automatically, you need to create all the tables and insert into each table at least one record template.
Handmade:
Create the folder app / Models / Schemas /
In this folder, create the files corresponding to each model. Its format is json.
"Field Name": "Data type"
For example:
User.json
{
"_id": "objectid",
"account": "string",
"name": "string",
"password": "string",
"roleIds": "array",
"permissionIds": "array",
"created_at": "moment",
"updated_at": "moment",
"roles": "function",
"permissions": "function",
"tokens": "function"
}
Acceptable data types:
string
number
array
object
moment
objectid
string
Query
Same as Lucid-mongo & mquery:
const users = await User.all()
const users = await User.where('name', 'peter').fetch()
const users = await User.where({ name: 'peter' })
.limit(10).skip(20).fetch()
const users = await User.where({
$or: [
{ gender: 'female', age: { $gte: 20 } },
{ gender: 'male', age: { $gte: 22 } }
]
}).fetch()
const user = await User
.where('name').eq('peter')
.where('age').gt(18).lte(60)
.sort('-age')
.first()
const users = await User
.where({ age: { $gte: 18 } })
.sort({ age: -1 })
.fetch()
const users = await User
.where('age', '>=', 18)
.fetch()
const users = await User
.where('age').gt(18)
.paginate(2, 100)
const users = await User.where(function() {
this.where('age', '>=', 18)
}).fetch()
const images = await Image
.where(location)
.near({ center: [1, 1] })
.maxDistance(5000)
.fetch()
const images = await Image
.where(location)
.near({ center: [1, 1], sphere: true })
.maxDistance(5000)
.fetch()
[More Documentation of mquery](https:
### [](https:
const count = await Customer.count()
const count_rows = await Customer
.where({ invited: { $exist: true } })
.count('position')
const max = await Employee.max('age')
const total_rows = await Employee
.where(active, true)
.sum('salary', 'department_id')
const avg_rows = await Employee
.where(active, true)
.avg('salary', { department: '$department_id', role: '$role_id' })
Aggregation
MQ-Models hỗ trợ aggregation.
sử dụng fetchAggregate() hoặc aggregate([....])
Example:
const users = await User.with('emails').fetchAggregate()
const users = await User.with('emails').aggregate([
$match: {
username: /ngoc/i
},
$unwind: {
path: 'emails',
preserveNullAndEmptyArrays: true
}
])
const users = await User.with('emails').where({username: "ngoc"}).fetchAggregate()
More: https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/
Auto unwind
By default, auto-unwind supports aggragation with dependencies: belongsTo,
hasOne, embedsOne, morphOne.
You can add more by overriding the autoUnwind function below:
static get autoUnwind(){
return [
"belongsTo",
"hasOne",
"embedsOne",
"morphOne"
]
}
lookup Recursive
Order.query.lookupRecursive({
'_id': 1,
'code': 1,
'customer_name': 1,
'type': 1,
'status': 1,
'OrderDetail': {
_id: 1,
quantity: 1,
Product: {
_id: 1,
name: 1
},
$match: {
quantity: {$gte: "4"}
}
},
$match: {
"OrderDetail._id" : {
$exists: true
}
}
}).fetchAggregate()
output:
{
"_id": "5bdc15838270df06b49008f8",
"code": "123456",
"customer_name": "日本㈱",
"type": "0",
"status": "1",
"customer_code": "12345",
"OrderDetail": [
{
"_id": "5bdfa2c23829550b884a6679",
"quantity": "5",
"Product": {
"_id": "5bd17ece0762192320a6d634",
"name": "L金型",
}
},
{
"_id": "5bdfa2c23829550b884a6672",
"quantity": "5",
"Product": {
"_id": "5bd17ece0762192320a6d634",
"name": "L金型",
}
},
{
"_id": "5bdfa2c23829550b884a66fd",
"quantity": "5",
"Product": {
"_id": "5bd17ece0762192320a6d634",
"name": "L金型",
}
},
{
"_id": "5bdfa2c23829550b884a6612",
"quantity": "5",
"Product": {
"_id": "5bd17ece0762192320a6d634",
"name": "L金型",
}
}
]
}
NgocHip