Mongoose 在egg中的使用详解

Mongoose是什么?

Mongoose是MongoDB的一个对象模型工具,封装了许多MongoDB对文档的的增删改查等常用方法,让NodeJS操作Mongodb数据库变得更加灵活简单。

在egg项目中如何使用?

1、安装

npm i egg-mongoose --save

2、配置

在根目录下的/config/plugin.js中配置插件

exports.mongoose = {
 enable: true,
 package: 'egg-mongoose',
};

3、连接数据库

在根目录下的/config/config.default.js增加配置,其中url为我们的数据库地址,可通过环境变量来区分开发环境还是生产环境,并且确定是否使用用户名密码的数据库
const prod = process.env.npm_config_server_prod;

mongoose: {
 client: {
 url: prod ? 'mongodb:eggadmin:123456@localhost:27017/DbName' : 'mongodb://127.0.0.1:27017/DbName',
 options: {
 useUnifiedTopology: true,
 },
 },
 },

4、配置与使用

(1)数据表配置

在app目录下新建model文件夹,在model文件夹下新建JS文件作为数据表的配置内容,下面以书籍表的配置为例

'use strict';

/**
 * @description: Mongoose book Schema,
 */

module.exports = app => {
 const mongoose = app.mongoose;
 const Schema = mongoose.Schema;
 const BookSchema = new Schema({
 desc: { type: String }, /* 书籍描述 */
 name: { type: String }, /* 书籍名称 */
 press: { type: String }, /* 出版社 */
 author: { type: String }, /* 作者 */
 image: { type: Array }, /* 书籍图片列表*/
 price: { type: String }, /* 价格 */
 book_type: { /* 书籍分类id */
 type: Schema.Types.ObjectId,
 ref: 'BookClassify',
 },
 user: { /* 书籍发布者id */
 type: Schema.Types.ObjectId,
 ref: 'User',
 },
 create_time: { type: String }, /* 创建时间 */
 status: { type: String }, /* 状态,1:待购买,2:已购买*/
 look: { type: Number } /* 浏览数量 */
 });
 return mongoose.model('Book', BookSchema);
};

可以看到我们可以通过Schema来定义表结构,可以指定字段的类型及关联,设置完字段后就可以生成model了,这里算是非常简单的配置,更多配置方法可参考文档

(2)、使用mongoose方法

配置完数据表结构后,我们就可以再service层中调用mongoose的方法对文档进行增删查改了,已书籍列表的处理逻辑为例子

async findbookList(data) {
 const { type, page, pageSize, desc, status, userId } = data;
 const searchVal = {}
 if (type) {
 searchVal.book_type = mongoose.Types.ObjectId(type)
 }
 if (status) {
 searchVal.status = status
 }
 if (userId) {
 searchVal.user = mongoose.Types.ObjectId(userId)
 }
 const search_term = {
 $or: [
 { desc: { $regex: desc ? desc : '', $options: '$i' } },
 { name: { $regex: desc ? desc : '', $options: '$i' } },
 { author: { $regex: desc ? desc : '', $options: '$i' } },
 { press: { $regex: desc ? desc : '', $options: '$i' } },
 ],
 };
 const totalNum = await this.ctx.model.Book.find(searchVal).and(search_term).countDocuments();
 const result = await this.ctx.model.Book.find(searchVal)
 .populate({
 path: 'user',
 select: { name: 1, image: 1 }
 })
 .populate({
 path: 'book_type'
 })
 .and(search_term)
 .sort({ create_time: -1 })
 .skip((parseInt(page) - 1) * parseInt(pageSize))
 .limit(parseInt(pageSize));
 return result ? { bean: {
 records: result,
 current: page,
 size: result.length,
 total: totalNum,
 }, ...app.config.msg.GET_SUCCESS } : app.config.msg.GET_ERR;
 }

可以看到,通过this.ctx.model.Book就可以获取到Book的model并且可以调用mongoose需要的方法,例如populate、find、and、sort、skip、limit 等等。

5、egg-Mongoose常用的方法

增加数据

this.ctx.model.Book.create(data,callback);

其中data为json数据结构,callback为操作后的回调函数

查询数据

获取所有数据,返回是一个数组

this.ctx.model.Book.find()

获取一个数据,返回是一个对象

this.ctx.model.Book.findOne()

条件查询

this.ctx.model.Article.find(conditions,callback);

其中conditions为查询的条件,callback为回调函数
conditions有一下几种情况:

具体数据:

this.ctx.model.Book.find
(
{_id:5c4a19fb87ba4002a47ac4d, name: "射雕英雄传"
}
, callback)
;

条件查询:

"$lt" 小于
"$lte" 小于等于
"$gt" 大于
"$gte" 大于等于
"$ne" 不等于
// 查询价格大于100小于200的书籍数组
this.ctx.model.Book.find({ "price": { $get:100 , $lte:200 }); 

或查询 OR

"$in" 一个键对应多个值
"$nin" 同上取反, 一个键不对应指定值
"$or" 多个条件匹配, 可以嵌套 $in 使用
"$not" 同上取反, 查询与特定模式不匹配的文档

this.ctx.model.Book.find({"name":{ $in: ["射雕","倚天"]} );

删除数据

this.ctx.model.Book.remove(conditions,callback);

更新数据

this.ctx.model.Book.update(conditions, update, callback)

conditions为条件,update是更新的值对象

排序

this.ctx.model.Book.sort({ create_time: -1 });

其中-1表示降序返回。 1表示升序返回

限制数量

this.ctx.model.Book.limit(number);

number表示限制的个数

跳过文档返回

this.ctx.model.Book.skip(number);

number表示跳过的个数,skip经常搭配limit实现分页的功能

条件数组and

在find后面可使用and对查询结果进行进一步条件筛选,相当于并且的意思。

const search_term = {
 $or: [
 { desc: { $regex: desc ? desc : '', $options: '$i' } },
 { name: { $regex: desc ? desc : '', $options: '$i' } },
 { author: { $regex: desc ? desc : '', $options: '$i' } },
 { press: { $regex: desc ? desc : '', $options: '$i' } },
 ],
 };
 this.ctx.model.Book.find().and(search_term)

关联查询populate

// 在model中配置字段时候指定关联的表名,就可以通过populate来进行表的关联查询
user: { /* 书籍发布者id */
 type: Schema.Types.ObjectId,
 ref: 'User',
 },

this.ctx.model.Book.find()
 .populate({
 path: 'user',
 select: { name: 1, image: 1 }
 })

聚合管道Aggregate

this.ctx.model.Template.aggregate([
 { $match: { name } },
 { $sort: { create_time: -1 } },
 { $group: { _id: '$name', user_id: { $first: '$modifier' } } },
 ]);

Mongoose聚合管道aggregate常用的操作有$project 、$match 、$group、$sort、$limit、$skip、$lookup 表关联

批量操作bulkWrite

const template_list = await ctx.model.Template.aggregate([
 { $sort: { create_time: -1 } },
 { $group: { _id: '$name', template_id: { $first: '$_id' }, label: { $first: '$label' } } },
 ]);
 const update_value = [];
 template_list.forEach(item => {
 if (!item.label) {
 update_value.push({
 updateOne: {
 filter: { _id: item.template_id },
 update: { label: '' },
 },
 });
 }
 });
 await ctx.model.Template.bulkWrite(update_value);

可以进行一系列批量增加、删除、更新等操作。

mongoose还有非常多的方法可以提供给我的灵活使用,我们在使用的时候可以结合业务逻辑选择合适的方法来提高我们操作数据库的效率。在我们使用它之前可以认真的阅读官方文档

总结

到此这篇关于Mongoose 在egg中的使用详解的文章就介绍到这了,更多相关egg中使用Mongoose内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 关于mongoose连接mongodb重复访问报错的解决办法

    具体代码如下所示: var express = require('express'); var mongoose = require('mongoose'); var router = express.Router(); var Person = mongoose.model('Person',{ id:Number, name:String }); /*新增*/ router.get('/insert', function(req, res){ var student = new Person

  • 利用Mongoose让JSON数据直接插入或更新到MongoDB

    前言 Nodejs基于Javascript,MongoDB脚步同样也是基于Javascript.而且他们的数据存储格式都是JSON,这就是为什么要把他们放在一起的原因了.如果程序前后端能直接处理JSON,我想数据处理过程又可以极大的减化了,代码量又将低少1/5.多么的兴奋啊!让我们来动手验证一下想法吧. 本文重点介绍web前端通过JQuery发起POST提交JSON数据,通过Mongoose直接插入或更新到MongoDB. 工程目录沿用nodejs-demo,增加/mongoose路径及对应文件

  • egg.js的基本使用和调用数据库的方法示例

    首先,整个项目的创建命令: npm i egg-init -g //安装egg egg-init egg-example --type=simple //初始化一个egg模板例子 后面的type跟的是模板类型这里是简单的 cd egg-example//进入例子 npm i //安装依赖 可以去官方教程查看基本配置的讲解. 直接说使用,简单看过Egg的文档,官方文档对于入门还是很实用的,再配合一些别人的攻略很容易入门上手就可以使用. 首先router.js: 'use strict'; /**

  • 关于在mongoose中填充外键的方法详解

    本文主要给大家介绍的是关于mongoose中填充外键的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: MongoDB MongoDB是典型的NoSQL数据库,因此不提供JOIN操作. 但有时我们仍然希望引用其他集合中的文档.此时便需要外键填充(population). mongoose是极具JavaScript特点的程序库,提供了极其简单和强大的填充功能. mongoose不仅支持填充单个文档,也支持多文档,甚至直接填充某个对象. 本文中部分代码来自mongoose文档

  • mongoose更新对象的两种方法示例比较

    前言 Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具 那么要使用它,首先你得装上node.js和mongodb,关于mongodb的安装和操作介绍可以参考:http://www.jb51.net/article/80296.htm 演示 描述场景 更新购物车数量与勾选状态 业务逻辑 查询到当前用户的购物车对象Cart,更新前端传递过来的quantity与selected字段 方法一 var _ = require('underscore'); Cart.f

  • 关于自定义Egg.js的请求级别日志详解

    Egg.js 是什么? Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本. 注:Egg.js 缩写为 Egg 背景 组织为了更好的对各个业务的请求日志进行统一的分析,制定了统一的日志打印规范,比如: [time][processId][traceId][userid] Hello World.... 统一格式之后,业务现有业务的日志工具打印出来的格式是无法满足该规范的,所以我们需要对此进行改造. 我们前端目前Node中间

  • 详解Nodejs基于mongoose模块的增删改查的操作

    MongoDB MongoDB是基于Javascript语言的数据库,存储格式是JSON,而Node也是基于JavaScript的环境(库),所以node和mongoDB的搭配能减少因为数据转换带来的时间空间开销. Mongoose 是MongoDB的一个对象模型工具,它将数据库中的数据转换为JavaScript对象以供你在应用中使用,封装了MongoDB对文档的的一些增删改查等常用方法,让NodeJS操作Mongodb数据库变得更加灵活简单. 安装模块mongoose npm install

  • KOA+egg.js集成kafka消息队列的示例

    Egg.js : 基于KOA2的企业级框架 Kafka:高吞吐量的分布式发布订阅消息系统 本文章将集成egg + kafka + mysql 的日志系统例子 系统要求:日志记录,通过kafka进行消息队列控制 思路图: 这里消费者和生产者都由日志系统提供 λ.1 环境准备 ①Kafka 官网下载kafka后,解压 启动zookeeper: bin/zookeeper-server-start.sh config/zookeeper.properties 启动Kafka server 这里conf

  • Mongoose 在egg中的使用详解

    Mongoose是什么? Mongoose是MongoDB的一个对象模型工具,封装了许多MongoDB对文档的的增删改查等常用方法,让NodeJS操作Mongodb数据库变得更加灵活简单. 在egg项目中如何使用? 1.安装 npm i egg-mongoose --save 2.配置 在根目录下的/config/plugin.js中配置插件 exports.mongoose = { enable: true, package: 'egg-mongoose', }; 3.连接数据库 在根目录下的

  • Java中的静态内部类详解及代码示例

    1. 什么是静态内部类 在Java中有静态代码块.静态变量.静态方法,当然也有静态类,但Java中的静态类只能是Java的内部类,也称为静态嵌套类.静态内部类的定义如下: public class OuterClass { static class StaticInnerClass { ... } } 在介绍静态内部类之前,首先要弄清楚静态内部类与Java其它内部类的区别. 2. 内部类 什么是内部类?将一个类的定义放在另一个类的内部,就是内部类.Java的内部类主要分为成员内部类.局部内部类.

  • Mysql中explain作用详解

    一.MYSQL的索引 索引(Index):帮助Mysql高效获取数据的一种数据结构.用于提高查找效率,可以比作字典.可以简单理解为排好序的快速查找的数据结构. 索引的作用:便于查询和排序(所以添加索引会影响where 语句与 order by 排序语句). 在数据之外,数据库还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用数据.这样就可以在这些数据结构上实现高级查找算法.这些数据结构就是索引. 索引本身也很大,不可能全部存储在内存中,所以索引往往以索引文件的形式存储在磁盘上. 我们

  • linux中 pmap 命令详解

    通过查看帮助,返回了如下信息: Usage: pmap [options] pid [pid ...] Options: -x, --extended show details -X show even more details WARNING: format changes according to /proc/PID/smaps -XX show everything the kernel provides -c, --read-rc read the default rc -C, --re

  • linux 中ls命令详解

    ls命令用来显示目标列表,在Linux中是使用率较高的命令.ls命令的输出信息可以进行彩色加亮显示,以分区不同类型的文件. 语法 ls(选项)(参数) 选项 -a:显示所有档案及目录(ls内定将档案名或目录名称为“.”的视为影藏,不会列出): -A:显示除影藏文件“.”和“..”以外的所有文件列表: -C:多列显示输出结果.这是默认选项: -l:与“-C”选项功能相反,所有输出信息用单列格式输出,不输出为多列: -F:在每个输出项后追加文件的类型标识符,具体含义:“*”表示具有可执行权限的普通文

  • Linux 中的通配符详解及实例

    Linux 中的通配符详解及实例 一 通配符  二 实战 [root@localhost ~]# mkdir dy [root@localhost ~]# cd dy [root@localhost dy]# touch dzp dzp2 dzp3 dzp34 dzpcang dzpbols [root@localhost dy]# ls dzp dzp2 dzp3 dzp34 dzpbols dzpcang [root@localhost dy]# la dzp bash: la: comma

  • java中正则表达式实例详解

    Java中正则表达式运用实例(参看java中正则表达式运用详解): 测试代码 package test; /** * 在String的matches()方法,split()方法中使用正则表达式. * @author fhd001 */ public class RegexTest { public static void main(String[] args) { /* * 普通字符 */ String str1 = "abc45abc345"; String[]arr1 = str1

  • Mybatis中 XML配置详解

    Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration> <

  • Java中初始化块详解及实例代码

    Java中初始化块详解 在Java中,有两种初始化块:静态初始化块和非静态初始化块. 静态初始化块:使用static定义,当类装载到系统时执行一次.若在静态初始化块中想初始化变量,那仅能初始化类变量,即static修饰的数据成员. 非静态初始化块:在每个对象生成时都会被执行一次,可以初始化类的实例变量. 非静态初始化块会在构造函数执行时,且在构造函数主体代码执行之前被运行. 括号里的是初始化块,这里面的代码在创建Java对象时执行,而且在构造器之前执行! 其实初始化块就是构造器的补充,初始化块是

  • Java中的HashSet详解和使用示例_动力节点Java学院整理

    第1部分 HashSet介绍 HashSet 简介 HashSet 是一个没有重复元素的集合. 它是由HashMap实现的,不保证元素的顺序,而且HashSet允许使用 null 元素. HashSet是非同步的.如果多个线程同时访问一个哈希 set,而其中至少一个线程修改了该 set,那么它必须 保持外部同步.这通常是通过对自然封装该 set 的对象执行同步操作来完成的.如果不存在这样的对象,则应该使用 Collections.synchronizedSet 方法来"包装" set.

随机推荐