1.0.2 • Published 5 years ago

@mqict/adonis-model v1.0.2

Weekly downloads
1
License
MIT
Repository
-
Last release
5 years ago

Welcome to MQ Adonisjs Model!

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 @mqict/adonis-model

in Models file: use use('@mqict/adonis-model') as BaseModel.

	const Model =  use('@mqict/adonis-model')
    class  User  extends  Model {
    	.....
    }

in start/app.js add command:

...
/*
|--------------------------------------------------------------------------
| Commands
|--------------------------------------------------------------------------
|
| Here you store ace commands for your package
|
*/
const commands = [
  '@mqict/adonis-model/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('@mqict/adonis-model')
    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()
    
    // to query geo near you need add 2d or 2dsphere index in migration file
	    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://github.com/aheckmann/mquery)
    
    ### [](https://github.com/duyluonglc/lucid-mongo#aggregation)Aggregation
    
      // count without group by
      const count = await Customer.count()
    
      // count group by `position`
      const count_rows = await Customer
        .where({ invited: { $exist: true } })
        .count('position')
    
      // max age without group by
      const max = await Employee.max('age')
    
      // sum `salary` group by `department_id`
      const total_rows = await Employee
        .where(active, true)
        .sum('salary', 'department_id')
    
      // average group by `department_id` and `role_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
	     }
	])
	//or
	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